Skip to content

fix: don't start the trigger after a Stop during scan pre-flight (#318) - #320

Merged
boringethan merged 1 commit into
nextfrom
feature/318-cancel-preflight-race
Oct 14, 2026
Merged

boringethan merged 1 commit into
nextfrom
feature/318-cancel-preflight-race

Conversation

@boringethan

@boringethan boringethan commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Pressing Stop right as a scan starts could land while the ScanWorkflow worker was still in its pre-flight, and cancel_scan()'s stop_trigger then reached the console before the worker's start_trigger. The window is about 0.3 s, roughly 2 s after Start in the app. The worker started the trigger anyway, so:

  • the trigger and laser ran for about 1 to 1.5 s after Stop;
  • the terminal fsync count was read mid-run and named a lit frame, giving TERMINAL DARK CONTAMINATED on every camera and an empty session deleted (app#726);
  • the cameras were disabled while FSYNC was still pulsing, which leaves still-powered cameras with corrupted receivers for the next scan (the 2026-10-12 case of app#722);
  • the app never saw trigger OFF ("trigger clock still open").

Root-cause write-up with the log evidence: OpenwaterHealth/openmotion-bloodflow-app#726 (comment)

Change

  • cancel_scan sets _cancel_requested before it stops the trigger.
  • A new _trigger_lock orders that stop against the worker's trigger start:
    • the worker skips start_trigger once a cancel has arrived;
    • a Stop that races an in-flight start_trigger waits for it, then stops the trigger.

Tests

Two new unit tests in tests/test_scan_workflow.py. Both fail on current next, where the console sees ['stop', 'fsync', 'start', 'stop'] (the order in the field logs), and pass with this change:

  • test_stop_during_preflight_never_starts_the_trigger
  • test_stop_while_the_trigger_starts_stops_it_afterwards

Hardware-free modules run: test_scan_workflow, test_pipeline/test_sources (minus the hardware smoke test), test_calibration_workflow, test_run_collection_scan, test_contact_quality_workflow, test_pipeline/test_packet_buffer and test_pipeline/test_public_api. All 89 tests pass.

Not yet verified on hardware. Bench check: in the app, press Stop about 2 s after Start (just as the scan begins). Expect:

  • no TERMINAL DARK ERROR lines;
  • no "trigger clock still open" warning;
  • the next contact-quality check is clean on the cameras that were in that scan's mask.

Closes #318
Refs OpenwaterHealth/openmotion-bloodflow-app#726

🤖 Generated with Claude Code

A Stop that landed while the scan worker was still in its pre-flight sent
cancel_scan's stop_trigger before the worker's start_trigger. The trigger
and laser then ran on after Stop, the terminal fsync count was read
mid-run and named a lit frame (TERMINAL DARK CONTAMINATED on every
camera), and the app never saw trigger OFF ("trigger clock still open").

cancel_scan now sets _cancel_requested before stopping, and a new
_trigger_lock orders its stop against the worker's trigger start: the
worker skips start_trigger once a cancel has arrived, and a Stop that
races an in-flight start_trigger waits for it and then stops it.

Refs #318
Refs OpenwaterHealth/openmotion-bloodflow-app#726

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: boringethan <ethan@openwater.cc>
@boringethan
boringethan force-pushed the feature/318-cancel-preflight-race branch from d491963 to 60faa3e Compare October 14, 2026 20:49
@boringethan
boringethan merged commit 8c527d8 into next Oct 14, 2026
2 checks passed
@boringethan boringethan mentioned this pull request Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant