feat(adapter): add Adapter.Reset() for in-process recovery#446
Conversation
|
Thank you for working on this @retr0h a couple quick things. Any new functions should be added to the interface definitions. Also at least no-op versions added to all platforms. We've been trying to get the consistency improved. Also, perhaps slightly briefer on the comments, if you please. 😸 Thanks! |
2207fe9 to
d80d0cd
Compare
Adds Reset() to *Adapter on all platforms. On darwin it tears down CoreBluetooth managers so a subsequent Enable() rebuilds from scratch. On linux it clears BlueZ handles. Other platforms are no-ops for interface symmetry. Also adds Reset() to the BLEAdapter interface definition. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
d80d0cd to
8dd1d1c
Compare
@deadprogram I've gone ahead and implemented your corrections. Let me know if you need anything else. |
|
Thank you very much for the useful addition @retr0h and the quick update. Now squash/merging! |
Adds Reset() to *Adapter on all platforms. On darwin it tears down CoreBluetooth managers so a subsequent Enable() rebuilds from scratch. On linux it clears BlueZ handles. Other platforms are no-ops for interface symmetry. Also adds Reset() to the BLEAdapter interface definition.
Bump tinygo.org/x/bluetooth to include tinygo-org/bluetooth#446 which adds Adapter.Reset() for in-process recovery. When Connect times out on a stale CBPeripheral handle (post-sleep/wake), call Reset() to tear down the central manager so the next Enable() rebuilds from scratch. Previously this required a process restart; now the reconnect loop recovers automatically. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
Adds
Reset()to*Adapteron darwin and linux.Resettears down the underlying transport-specific state (CoreBluetooth managers on darwin, D-Bus handles on linux) so a subsequentEnable()rebuilds them from scratch.Depends on #445 (Enable callable after first invocation) — once that lands I'll rebase and remove this note.
Motivation
There's currently no API to throw away adapter state and start fresh on the same
*Adapter. Useful for:What it does
StopScanConnectwaiters viaclose(ch)so callers unblock and return an error rather than parking on a callback that a fresh central will never delivercm/pmwith freshcbgo.NewCentralManager(nil)/cbgo.NewPeripheralManager(nil); ARC reclaims the old onespoweredChan,scanChan,peripheralFoundHandler)After Reset, calling
Enable()again is required to set up fresh delegates and wait for powered-on. This relies on Enable'spoweredChan-cleanup behavior in #445, which is why the two PRs are stacked.Honest about the limits
The doc comment is explicit about what Reset does not do:
I empirically validated this in a real recovery flow: after a long macOS sleep, ~20 Reset cycles over 10 hours never restored the ability to re-discover a known peripheral. The dedup table outlives any in-process API we have access to. Recovery from that specific failure mode requires self-exec or a subprocess BLE helper — out of scope for this library.
That said, Reset still has a useful niche:
Linux
Mostly a no-op — BlueZ is naturally per-call and doesn't carry the kind of cached peripheral state that wedges CoreBluetooth — but keeps the API symmetric so callers can write platform-agnostic recovery code.
Caller contract
Caller MUST ensure no
Scan/Connect/DiscoverServicesis in flight when Reset is called — there is no internal locking. Documented in the comment. The intended usage pattern is:Verification
go build .clean on darwin/arm64Connect. Post-Reset,Connectreturns an error from the closed connectMap channel, the caller logs it and retries the full scan-and-connect path on the new central.Backwards compatibility
Purely additive. Existing callers see no change.
🤖 Generated with Claude Code