Hyprland module-host timeout leaves socket work alive and executes fallback after failure #46

Closed
opened 2026-10-14 18:21:59 +08:00 by Breadway · 2 comments
Owner

Found during independent review of Breadway/bread PR44, exact head 44a5a0b740. Confidence high: real daemon and sandboxed host with private fake compositor reproduce. Evidence /tmp/opencode/review-pr44/timeout-probe.py and timeout-probe.log on hermes. Repair on existing PR44, not a duplicate PR. breadd/src/ipc/module_host_bridge.rs:587-590 times out a spawn_blocking JoinHandle without cancelling the blocking work. hyprland_compat.rs:63-71 has no socket read/write deadline or reply-size cap. Fake compositor receives dispatch at 1.6s, stalls 9.5s, then rejects it. Module already receives hyprland request timed out, but daemon still sends eval hl.dispatch(...) at 11.1s. Thus commands can execute after reported failure and caller retry, blocked workers can accumulate, and shutdown can wait indefinitely. Bound the actual transport/operation lifetime across fallback and read-back, prevent any further request after expiry, bound request/reply bytes and in-flight work, and add stalled/late/oversized response regressions.

Found during independent review of Breadway/bread PR44, exact head 44a5a0b7407a4c4b8052a75134e3a478dcc64503. Confidence high: real daemon and sandboxed host with private fake compositor reproduce. Evidence /tmp/opencode/review-pr44/timeout-probe.py and timeout-probe.log on hermes. Repair on existing PR44, not a duplicate PR. breadd/src/ipc/module_host_bridge.rs:587-590 times out a spawn_blocking JoinHandle without cancelling the blocking work. hyprland_compat.rs:63-71 has no socket read/write deadline or reply-size cap. Fake compositor receives dispatch at 1.6s, stalls 9.5s, then rejects it. Module already receives hyprland request timed out, but daemon still sends eval hl.dispatch(...) at 11.1s. Thus commands can execute after reported failure and caller retry, blocked workers can accumulate, and shutdown can wait indefinitely. Bound the actual transport/operation lifetime across fallback and read-back, prevent any further request after expiry, bound request/reply bytes and in-flight work, and add stalled/late/oversized response regressions.
Author
Owner

Exact-head re-review at 5ed063907a: original late-after-timeout defect is repaired (independent 8.006s timeout, only initial dispatch, no fallback). Remaining R1 lifecycle defect reproduced against real daemon + authenticated sandboxed fake host: initial dispatch at0.083s, exact fake_module_host PID SIGKILL at0.083s, /proc/PID/exe absent afterwards, compositor rejects at2.083s and daemon still sends eval hl.dispatch(...) at2.083s. High confidence, probe /tmp/opencode/review-pr44/disconnect-probe.py and .log. module_host_bridge.rs:128-162 awaits dispatch without monitoring connection EOF; HyprlandSession.closed is set only on Drop at178, after operation completes. Unit dropping_the_host_session_stops_an_in_flight_operation manually drops session and misses real lifecycle. Repair same PR44: observe actual disconnect concurrently and signal cancellation promptly, no fallback/read-back after disconnect, release permits. Add real host-close/death regression. Related test defect: deadlines.rs:191-203 rewrites script and go on an already exited one-shot fake host (examples/fake_module_host.rs reads script once and exits), so its second in-flight shutdown scenario never starts. Reviewer separate shutdown probe observed initial request then SIGTERM: exit0 in0.007s and no fallback. Keep regression but make it observe a genuinely live second stalled call before termination. No source changes or merge.

Exact-head re-review at 5ed063907adae3e44e0799a18586efb3298a9624: original late-after-timeout defect is repaired (independent 8.006s timeout, only initial dispatch, no fallback). Remaining R1 lifecycle defect reproduced against real daemon + authenticated sandboxed fake host: initial dispatch at0.083s, exact fake_module_host PID SIGKILL at0.083s, /proc/PID/exe absent afterwards, compositor rejects at2.083s and daemon still sends eval hl.dispatch(...) at2.083s. High confidence, probe /tmp/opencode/review-pr44/disconnect-probe.py and .log. module_host_bridge.rs:128-162 awaits dispatch without monitoring connection EOF; HyprlandSession.closed is set only on Drop at178, after operation completes. Unit dropping_the_host_session_stops_an_in_flight_operation manually drops session and misses real lifecycle. Repair same PR44: observe actual disconnect concurrently and signal cancellation promptly, no fallback/read-back after disconnect, release permits. Add real host-close/death regression. Related test defect: deadlines.rs:191-203 rewrites script and go on an already exited one-shot fake host (examples/fake_module_host.rs reads script once and exits), so its second in-flight shutdown scenario never starts. Reviewer separate shutdown probe observed initial request then SIGTERM: exit0 in0.007s and no fallback. Keep regression but make it observe a genuinely live second stalled call before termination. No source changes or merge.
Author
Owner

Coordinator verification on the same integrated merge d5748d6093 (PR44). Bound transport lifetime, no post-expiry request, request/reply byte caps and in-flight limits are covered by the deadlines suite 6/6 plus wire 3/3 and host 4/4 on the merge tree. Independent pass at b05a6f6 (comment 5360, criterion R1) retained. Fake compositor and private sockets only; no host compositor.

Coordinator verification on the same integrated merge d5748d6093def1c4863bd496c86af0be31f8c6f1 (PR44). Bound transport lifetime, no post-expiry request, request/reply byte caps and in-flight limits are covered by the deadlines suite 6/6 plus wire 3/3 and host 4/4 on the merge tree. Independent pass at b05a6f6 (comment 5360, criterion R1) retained. Fake compositor and private sockets only; no host compositor.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Breadway/bread#46
No description provided.