Files
buzz/crates
npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67dandTyler Longwell e1a8103715 fix(relay): bound log-guard drop so shutdown can't deadlock on a wedged stdout
Review finding on #3256 (Dawn reproduced it standalone; Max flagged the
same path from source): upstream WorkerGuard::drop, when the queue is
full, times out its 100ms shutdown send and then println!s -- into the
exact stdout whose lock the worker thread holds while parked in write(2)
on the full pipe. Deadlock in the shutdown path of the change that exists
to fix shutdown. The prior tests missed it because both unblocked the
sink before dropping the guard.

Fix: BoundedWorkerGuard wraps the upstream guard and runs its drop on a
sacrificial named thread, waiting at most 2s (upstream's healthy drop is
internally bounded at ~1.1s). Healthy shutdown keeps the full flush;
a wedged pipe costs the queued lines -- already this module's stated
loss policy -- and process exit reaps the abandoned thread. If thread
spawn fails, the guard is leaked (ManuallyDrop), never dropped inline:
lost lines, never a hang. non_blocking_stdout() returns the wrapper, so
every exit path of main is covered with no call-site changes.

Tests:
- guard_drop_bounded_with_wedged_stdout_through_process_exit: subprocess
  regression at the process level. Child re-execs with stdout piped and
  never read (the exact production wedge), saturates pipe + queue
  (proven via dropped_lines() > 0, reported over stderr), drops the
  guard, exits; parent asserts clean exit within deadline. Verified the
  test catches the bug: with the raw upstream drop inlined it hangs the
  child and fails on the deadline.
- bounded_guard_flushes_on_healthy_shutdown: the wrapper still delivers
  the upstream flush when the sink is healthy.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-27 22:56:13 -04:00
..
2026-07-27 14:18:24 -04:00