Skip to content

Fix intermittent hang in OISpectrometer.getSpectrum#103

Merged
dccote merged 1 commit into
masterfrom
fix/oceaninsight-getspectrum-hang
Jul 6, 2026
Merged

Fix intermittent hang in OISpectrometer.getSpectrum#103
dccote merged 1 commit into
masterfrom
fix/oceaninsight-getspectrum-hang

Conversation

@dccote

@dccote dccote commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

OISpectrometer.getSpectrum (inherited by USB2000Plus, 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 maxRequests requests (default 4), each awaited up to maxWait seconds (default 2.0). Raise the existing SpectrumRequestTimeoutError in bounded time instead of looping. Transient usb.core.USBError (incl. USBTimeoutError) raised while polling is absorbed and retried rather than propagating on the first hiccup.

integrationTime stays the first optional argument (back-compatible with every caller); subclasses that override getSpectrumData still inherit this getSpectrum.

Test plan

  • testOISpectrometer.py (new, hardware-free mock): with isSpectrumReady always False, getSpectrum(maxRequests=2, maxWait=0.05) raises SpectrumRequestTimeoutError in < 10s instead of blocking; also verifies the happy path and the request cap. 3 passed.
  • Live hardware: 25 consecutive getSpectrum() on the real USB2000+ — 1870 points each, ~14 ms/call, worst 39 ms, no hang. Confirms normal operation is unaffected.
  • Full suite run to confirm no caller relied on the infinite-wait behavior (testLabjackU3.py errors on collection only because the u3 library is not installed — unrelated).

🤖 Generated with Claude Code

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>
@dccote
dccote merged commit 651f8de into master Jul 6, 2026
14 checks passed
@dccote
dccote deleted the fix/oceaninsight-getspectrum-hang branch July 6, 2026 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant