Commit 47a9222
committed
fix(llmloop): scope async memory compression to each RunPerFile conversation
The Runner is shared by all concurrent per-file review goroutines, but it
held a single compressionMu/pendingJob slot for async memory compression.
With concurrency > 1 that shared slot caused four defects (#384):
1. Cross-file apply: tryApplyPendingCompression had no owner check, so
file B could splice file A's rebuilt history into its own messages.
2. Cross-file cancel/replace: the warning-threshold paths canceled
whichever file's job happened to be pending, surfacing spurious
"context canceled" errors at the gateway; triggerAsyncCompression
overwrote the slot unconditionally, wasting the superseded request.
3. Same-call start-then-cancel: the soft-threshold trigger fired before
the new messages were appended, so an append that crossed the warning
threshold canceled the job started microseconds earlier.
4. The pendingJob == nil fast-path read in addNextMessage was unlocked.
Fix: move the bookkeeping into a compressionState owned by each
RunPerFile call and thread it through trigger/apply/cancel. The
nil-pending gate is now an atomic check-and-set inside
triggerAsyncCompression under st.mu, and the async trigger moved to the
end of addNextMessage, gated on the post-append count sitting strictly
between the soft and warning thresholds. RunPerFile defers a cancel so
no job outlives its conversation. Aggregate token counters and warnings
stay Runner-level.
Intentional behavior deltas, all strictly safer: the async snapshot now
includes the just-appended round; an in-flight job is canceled when
RunPerFile returns instead of running up to 5 minutes orphaned; no async
job starts when the call is about to return false.
Verified: new regression tests (cross-file isolation via a channel-gated
fake client, owner-only summary apply with post-snapshot suffix
preserved, no start-then-cancel in one update, 4 concurrent RunPerFile
calls under -race); all existing compression tests updated to the
per-conversation API; full suite green with -race; coverage 81.1%.
E2E: 2-file concurrent review against a local OpenAI-compatible stub
with compression exercised — zero "context canceled", both files done.
Fixes #3841 parent 0b226fa commit 47a9222
3 files changed
Lines changed: 337 additions & 62 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
41 | 42 | | |
42 | 43 | | |
43 | 44 | | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
44 | 55 | | |
45 | 56 | | |
46 | 57 | | |
| |||
252 | 263 | | |
253 | 264 | | |
254 | 265 | | |
255 | | - | |
256 | | - | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
257 | 276 | | |
258 | | - | |
259 | 277 | | |
260 | | - | |
261 | 278 | | |
262 | | - | |
263 | | - | |
264 | | - | |
| 279 | + | |
| 280 | + | |
265 | 281 | | |
266 | 282 | | |
267 | 283 | | |
268 | 284 | | |
269 | 285 | | |
270 | | - | |
271 | | - | |
| 286 | + | |
| 287 | + | |
272 | 288 | | |
273 | | - | |
| 289 | + | |
274 | 290 | | |
275 | 291 | | |
276 | 292 | | |
277 | 293 | | |
278 | 294 | | |
279 | | - | |
| 295 | + | |
280 | 296 | | |
281 | 297 | | |
282 | 298 | | |
| |||
288 | 304 | | |
289 | 305 | | |
290 | 306 | | |
291 | | - | |
292 | | - | |
293 | | - | |
294 | | - | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
295 | 311 | | |
296 | 312 | | |
297 | 313 | | |
| |||
300 | 316 | | |
301 | 317 | | |
302 | 318 | | |
303 | | - | |
304 | | - | |
| 319 | + | |
| 320 | + | |
305 | 321 | | |
306 | 322 | | |
307 | 323 | | |
| |||
311 | 327 | | |
312 | 328 | | |
313 | 329 | | |
314 | | - | |
315 | | - | |
| 330 | + | |
| 331 | + | |
316 | 332 | | |
317 | | - | |
| 333 | + | |
318 | 334 | | |
319 | 335 | | |
320 | 336 | | |
321 | 337 | | |
322 | 338 | | |
323 | 339 | | |
324 | | - | |
325 | | - | |
326 | | - | |
327 | | - | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
328 | 345 | | |
329 | | - | |
330 | | - | |
331 | | - | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
332 | 349 | | |
333 | 350 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
42 | | - | |
43 | | - | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
44 | 45 | | |
45 | 46 | | |
46 | 47 | | |
| |||
51 | 52 | | |
52 | 53 | | |
53 | 54 | | |
54 | | - | |
55 | | - | |
56 | 55 | | |
57 | 56 | | |
58 | 57 | | |
| |||
153 | 152 | | |
154 | 153 | | |
155 | 154 | | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
156 | 160 | | |
157 | 161 | | |
158 | 162 | | |
| |||
250 | 254 | | |
251 | 255 | | |
252 | 256 | | |
253 | | - | |
| 257 | + | |
254 | 258 | | |
255 | 259 | | |
256 | 260 | | |
| |||
430 | 434 | | |
431 | 435 | | |
432 | 436 | | |
433 | | - | |
| 437 | + | |
434 | 438 | | |
435 | 439 | | |
436 | 440 | | |
437 | 441 | | |
438 | | - | |
439 | | - | |
440 | | - | |
| 442 | + | |
441 | 443 | | |
442 | | - | |
443 | | - | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
444 | 448 | | |
445 | | - | |
446 | | - | |
447 | | - | |
448 | | - | |
449 | | - | |
450 | 449 | | |
451 | 450 | | |
452 | 451 | | |
| |||
461 | 460 | | |
462 | 461 | | |
463 | 462 | | |
464 | | - | |
| 463 | + | |
465 | 464 | | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
466 | 473 | | |
467 | 474 | | |
468 | | - | |
| 475 | + | |
469 | 476 | | |
470 | 477 | | |
471 | 478 | | |
| |||
0 commit comments