Repository navigation
feat: auto-reconnect the ibidi multiplexer on a dropped USB link - #55
Merged
Merged
Conversation
When a command's retries are exhausted (the link genuinely dropped), the driver now attempts a bounded recovery before raising: it re-establishes the link for up to reconnect_timeout seconds (default 120, configurable), trying the same COM port first (USB selective-suspend / transient glitch) and then re-discovering the SAME USB device on a possibly-new port (matched by VID/PID/serial via serial.tools.list_ports, so other instruments are never opened). A brief drop/replug resumes the run transparently instead of aborting it; the keep-alive self-heals an idle drop before the next command. A truly dead device still aborts after the window, preserving the v0.3.4 no-forever-hang guarantee. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Addresses four issues found reviewing the auto-reconnect PR: 1. Keep-alive no longer runs _recover_link itself. On a dead link that recovery could run up to reconnect_timeout (120s), outliving _stop_keepalive()'s bounded ~3s join and racing close()'s self._serial=None teardown (reopen-after-close / AttributeError). The keep-alive now only detects+logs; recovery is the next real command's job. 2. Gate recovery on a new self._connected flag (set at end of connect(), cleared in close()). A wedged device at the initial identify() handshake no longer hangs connect() for the whole window before failing. 3. _write_read raises a clean SerialException when self._serial is None (closed concurrently) instead of an AttributeError; _try_relink bails rather than re-opening the port after close. 4. Fix the DEFAULT_RECONNECT_TIMEOUT comment: the override lives in the setup's hamilton.ibidi: block, not a `multiplexer:` block. New tests: no recovery before connect; _write_read raises cleanly after close; _try_relink does not resurrect the handle after close. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Makes a dropped ibidi USB link a recoverable blip instead of an aborted run. Builds on v0.3.4 (which stopped the multi-day hang); this adds transparent recovery so a brief drop/replug doesn't cost the experiment.
How
When a valve/pump command's normal retries are exhausted (the link genuinely dropped),
_commandnow attempts a bounded auto-reconnect before raising:serial.tools.list_ports). It only ever opens this device's ports, so a blind reconnect can never disturb another instrument on the rig (Hamilton pumps, Arduino, lasers, …).reconnect_timeout(default 120 s, configurable via the setup'sibidi:block;0disables). If the window expires, it still raises → loud abort — preserving the v0.3.4 "never a forever-hang" guarantee.Recovery is single-flight (
_reconnect_lock), interruptible byclose()and orchestration abort, and never holds the IO lock across the whole window.Behaviour summary
reconnect_timeout(loud, no hang)Tests
New
IbidiReconnectTest: command recovers via reconnect; still raises after the window expires;reconnect_timeout=0raises immediately (no recovery); relink candidates are same-port-first then the matched device only (never a foreign port); USB identity is recorded for the connected port. Existing 36 ibidi tests + the Legacy integration + emulator/services suites all green;black/flake8clean.🤖 Generated with Claude Code