fix(acpmux): surface outbound queue gaps (#21000)

Merged
TE
13d ago
+214-11

Fixes #21000

ACPMUX silently drops outbound messages when a slow client fills its bounded output queue.

The bounded outbound queue now reserves capacity for an RPC response and a recovery marker. When notification delivery is rejected by queue pressure, ACPMUX emits _acpmux/lagged with reason: output_queue_full and a cumulative dropped count so clients can replay from their cursor. Inventory-watch notifications follow the same reserve policy.

Changelog

  • ACPMUX reports outbound queue gaps and preserves response/control capacity for reconnect recovery.

Verification

  • python3 scripts/cmux-next/prepush-gate.py — passed on 4849c970882c9dd7b2cefc4b9e359152e7541a95.
  • cargo fmt --manifest-path cmux-tui/Cargo.toml --all -- --check — passed.
  • Hosted focused verification run 40068104184 is bound to the exact head; Linux test is still running. Other jobs have independent runner/base failures (MSRV, macOS setup, cross-build, clippy/panic ratchet) and are recorded as base/infrastructure findings.

Agent session: huge-blue


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes outbound queue backpressure in ACPMUX so slow clients get a replay signal instead of silently dropped notifications, while always reserving capacity for RPC responses.

  • Reserves queue slots for responses and the _acpmux/lagged recovery marker so notifications can't crowd out replies.
  • Queues _acpmux/lagged with reason: output_queue_full and a cumulative dropped count when notifications are dropped; oversized notifications report reason: message_too_large.
  • Serializes capacity checks and enqueues across request, inventory-watch, and inventory-disable paths so gap delivery and the disable reply stay ordered; when the queue is full, the marker waits for the next free slot so even a quiet reader eventually receives it.
  • Closes pending gap waiters when the connection tears down, so no task leaks after disconnect.