Conversation
|
| } | ||
| if let Some(_lease) = acquire_session_lease(receiver_access, &mut state.lease) { | ||
| retry_pending_restores(&mut state.slots, &channels.registry, Instant::now()).await; | ||
| retry_pending_restores(&mut state.slots, &channels.registry, &[], Instant::now()).await; |
There was a problem hiding this comment.
Shutdown retries obsolete route
If a device moves from route A to B and then back to A or onward to C while the first handoff is still draining, the restore token retains route B because draining sessions ignore later plan changes. This shutdown path passes an empty plan list, so it repeatedly retries obsolete route B instead of the latest reachable route. Confirmed replacement can remain blocked indefinitely, while terminal shutdown can time out and leave the controls diverted.
Knowledge Base Used:
Summary
Rebase of #1198 (originally by @justinechang39, branch
fix/multi-receiver-capture-route) onto currentmaster, opened here because pushing directly to the original fork branch was denied (403) despitemaintainerCanModifybeing set.Fixes HID++ button capture becoming stuck when one physical mouse moves between receiver routes (e.g. two Bolt receivers). A retiring capture session now restores firmware state through the newly active route before allowing its successor to arm. Pending restoration retries also follow the latest route for the same physical device.
Changes
openlogi-device
CaptureSessionStop,CaptureStop::Handoff).PendingCaptureRestore::retry_via).openlogi-agent-core
CaptureSession::reconcile_with).No configuration or IPC wire-format changes.
Rebase notes
Master had meanwhile consolidated
CaptureSessioninto aCaptureSlot<Target, Dispatch, Restore>wrapper (Running/Recovering) and renamed the manager'spending_restoresmap toslots(#1321-era work). Resolved by makingCaptureSlotgeneric over the newStoptype parameter as well, and threadingretry_via's route lookup through theslots-based structure instead of the pre-refactor flat map. Also updated a shutdown call site and a replay test (session_replay_tests.rs) that weren't part of the textual conflict but broke onCaptureSessionStopbecoming the shutdown channel's payload type.Testing
Full local gate on the rebased tip (Linux):
cargo fmt --all -- --checkRUSTFLAGS="-D warnings" cargo clippy --workspace --all-targets -- -D warningsRUSTFLAGS="-D warnings" cargo test --workspaceRUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps --document-private-items --exclude openlogi-ui --exclude openlogi-desktop --exclude openlogi-overlay --exclude openlogi-agentAll green. The original PR's tests exercise the actual handoff scenario directly: a unit test proving
reconcile_withemitsHandoff(successor_route)on a route change, plus async integration tests for following a device to a new route, remembering a route that appears later, and bouncing back to the original route on a rapid switch. No additional test was needed beyond what #1198 already included.Hardware verification status: not verified by anyone maintaining this fix. The original author reproduced the failure on an MX Master 4 with two Bolt receivers but has not hardware-verified this patch (no compatible Xcode/Metal toolchain for their test Mac). This rebase only re-validates the local gate; it does not add hardware verification.
Fixes #1196