Fix intermittent hang in OISpectrometer.getSpectrum#103
Merged
Conversation
Problem: getSpectrum waited for the 'spectrum ready' flag in an unbounded loop; on a transient USB glitch the flag could stay down, so it re-requested a spectrum forever (process pinned ~30% CPU, never returning). Seen intermittently on an USB2000+ during long repeated acquisitions. Solution: bound the wait — at most maxRequests requests (default 4), each awaited up to maxWait seconds (default 2.0). Raise the existing SpectrumRequestTimeoutError in bounded time instead of looping. Absorb transient usb.core.USBError (incl. USBTimeoutError) from requestSpectrum()/isSpectrumReady() and retry rather than propagating on the first hiccup. integrationTime stays the first optional argument for back-compatibility; subclasses that override getSpectrumData still inherit this getSpectrum. Adds testOISpectrometer.py (hardware-free mock) verifying the bounded-timeout and happy paths. 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.
Summary
OISpectrometer.getSpectrum(inherited byUSB2000Plus,USB4000_2000Plus,USB4000,USB2000, …) waited for the "spectrum ready" flag in an unbounded loop. On a transient USB glitch the flag could stay down, so it re-requested a spectrum forever — the process pinned ~30% CPU and never returned. Seen intermittently on a USB2000+ during long repeated acquisitions.Fix
Bound the wait: at most
maxRequestsrequests (default 4), each awaited up tomaxWaitseconds (default 2.0). Raise the existingSpectrumRequestTimeoutErrorin bounded time instead of looping. Transientusb.core.USBError(incl.USBTimeoutError) raised while polling is absorbed and retried rather than propagating on the first hiccup.integrationTimestays the first optional argument (back-compatible with every caller); subclasses that overridegetSpectrumDatastill inherit thisgetSpectrum.Test plan
testOISpectrometer.py(new, hardware-free mock): withisSpectrumReadyalways False,getSpectrum(maxRequests=2, maxWait=0.05)raisesSpectrumRequestTimeoutErrorin < 10s instead of blocking; also verifies the happy path and the request cap. 3 passed.getSpectrum()on the real USB2000+ — 1870 points each, ~14 ms/call, worst 39 ms, no hang. Confirms normal operation is unaffected.testLabjackU3.pyerrors on collection only because theu3library is not installed — unrelated).🤖 Generated with Claude Code