ACP turn-done races notification drain, causing response backlog #259

Closed
opened 2026-09-12 19:49:53 +01:00 by naps62-yolo · 0 comments
Collaborator

The finish_queued_acp_turn spawned task can grab the AcpEventStream lock before the event pump has persisted all notification chunks for the finishing turn. The turn-end row is appended and broadcast mid-stream, so:

  • The client sees turn.responding = false before all content chunks arrive
  • If queued prompts exist, the next turn begins before the previous response is fully delivered
  • From the user's perspective, responses appear delayed or only show up when they type a new message

Root cause: on_receiving_result fires the done oneshot in the ACP dispatch loop, which is ordered after all notifications on the wire. But done.await wakes a separate tokio task that contends for the stream lock independently of the event pump task draining updates_tx.

Fix: route turn-done through the same updates_tx channel as notifications so the event pump sees it in FIFO order, after every notification chunk. The pump signals the done oneshot only after persisting all preceding notifications.

The `finish_queued_acp_turn` spawned task can grab the `AcpEventStream` lock before the event pump has persisted all notification chunks for the finishing turn. The turn-end row is appended and broadcast mid-stream, so: - The client sees `turn.responding = false` before all content chunks arrive - If queued prompts exist, the next turn begins before the previous response is fully delivered - From the user's perspective, responses appear delayed or only show up when they type a new message Root cause: `on_receiving_result` fires the `done` oneshot in the ACP dispatch loop, which is ordered after all notifications on the wire. But `done.await` wakes a separate tokio task that contends for the stream lock independently of the event pump task draining `updates_tx`. Fix: route turn-done through the same `updates_tx` channel as notifications so the event pump sees it in FIFO order, after every notification chunk. The pump signals the done oneshot only after persisting all preceding notifications.
This repo is archived. You cannot comment on issues.
1 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: naps62/maestro#259