Repository navigation
fix(ble): close the FlutterBluePlus scan stream before cleanup can block it - #144
shroominic wants to merge 1 commit into
Conversation
FlutterBluePlusTransport.scan returned a stream that outlived the scan. flutter_blue_plus stops the radio at its own timeout, but the transport's cleanup awaited cancelResults, cancelScanning, awaitPendingStart, and stopScan before closeController. On a stack that leaves any of those pending, controller.close() never ran, so callers waited forever and cancelling the subscription hung for the same reason. - close the caller's stream first in closeFlutterBluePlusScanResources, - bound each cleanup step so a pending plugin future cannot hold a caller, - arm a scan deadline so a scan still closes when the plugin stops the radio without publishing isScanning = false, - cover it with a regression test that drives cleanup with futures that never complete. Measured before the fix on a Pixel 6: a 6 s window left isScanningNow false at ~7 s while the transport stream was still open at 12 s, and a 25 s timeout on the stream fired, while the plugin's raw result stream delivered 429 advertisements in the same period. Fixes #143.
|
Cross-lane note from the device-session lane: this PR's scan shape is now mirrored by the device harness, so the two paths stay comparable.
No file this PR owns was touched. Nothing here needs a change on this branch; this is only so the next reviewer of |
|
Carried by the GS1 consolidation in PR #209 (branch feature/cbio-gs1, head 3eca4f4). This PR is contained in the consolidated line; the merge that carries it is c85f827. Closing as subsumed by the consolidation - not as won't fix. The per-defect evidence stays in this thread, and the carrying commit above is where the change now lives. |
Fixes #143.
The defect
FlutterBluePlusTransport.scanhanded callers a stream that outlived the scan.When
flutter_blue_plusstopped the radio at its owntimeout, the transportcalled
closeStreamSafely(stopScan: false)→closeFlutterBluePlusScanResources,which awaited
cancelResults,cancelScanning,awaitPendingStart, andstopScanbeforecloseController. Any of those plugin futures stayingpending on a real stack means
controller.close()never runs: the caller waitsforever, and cancelling the subscription hangs too.
Every app scan goes through this transport, so the nearby-sensor list sat on
"Looking for supported sensors nearby…" indefinitely and no driver was ever
selectable — even with the sensor advertising on the same phone's Bluetooth page.
Measured before the fix (Pixel 6, 6 s scan window)
FlutterBluePlus.isScanningNowfalseat ~7 s.timeout(25 s)on the streamonScanResultsThe radio and the plugin were healthy; only this wrapper was wedged.
The fix
closeFlutterBluePlusScanResourcescloses the caller's stream first, thenruns the plugin cancellations, each bounded by
stepTimeout(default 5 s).scanarms a deadline fortimeout + 750 msso a scan closes even when theplugin stops the radio without publishing
isScanning = false.the old sequence that caused the hang.
Regression test
flutter_blue_plus_scan_close_test.dartdrives the cleanup primitive withfutures that never complete and asserts the stream still closes and cleanup
still returns. It fails on the previous ordering and passes now.
Verification
packages/cgm_ble_flutter:flutter analyzeclean,flutter test27 passed.(
1 sensor found) and connects; see the app-integration PR for the screenevidence.
This branch is based on
feature/cbio-gs1-glucose-live, the branch that carriesthe current
FlutterBluePlusTransport; the equivalent fix does not exist onmainyet.