You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In the CoreBluetooth backend, the advertisement handlers look a peripheral up in self.peripherals and send an event to its event_sender. If that send fails because the receiver has been dropped, the error is logged but the peripheral is never removed from the map. Every subsequent advertisement packet from that peripheral repeats the same failing send and the same log line, for the lifetime of the adapter.
Observed as a continuous flood of:
Error sending notification event: send failed because receiver is gone
at sub-millisecond intervals.
Affected code
src/corebluetooth/internal.rs on main, all following the same shape:
on_peripheral_disconnect (L807) and the handler at L919 share the pattern, though those are not advertisement-rate so they are far less visible.
Why it matters
A dead receiver is terminal — nothing will ever read from that channel again — but the send is retried at advertisement rate, which during active scanning is every few milliseconds per peripheral. The cost is not just noise:
Each failure formats and emits a log record. Downstream consumers that ship logs somewhere (a UI log view, a file, a crash reporter) do real work per line.
Applications with a synchronous or bounded logging pipeline can have the emitting thread stalled by the volume. We hit exactly this in Intiface Central: the flood saturated a bounded log channel whose producer side blocked, which stalled the tokio worker driving the CoreBluetooth event loop and stopped BLE command delivery entirely (iOS stops sending commands when screen turns off intiface/intiface-central#270).
Reproduction
Drop the Peripheral while the physical device is still advertising and scanning is still active. Concretely, in our case: stop the engine, change device configuration, restart the engine — the old Peripheral objects are dropped while CoreBluetooth keeps delivering adverts for the same UUIDs.
Suggested fix
Treat a send error as terminal for that peripheral and drop it from the map, so at most one error is logged per peripheral:
Whether outright removal is correct depends on whether a peripheral is expected to be re-registered later by UUID; if so, clearing or replacing the sender would be the safer variant. Downgrading these particular sites from error! to debug!/trace! would also help, since a dropped receiver is a normal consequence of the consumer going away rather than a fault.
Summary
In the CoreBluetooth backend, the advertisement handlers look a peripheral up in
self.peripheralsand send an event to itsevent_sender. If that send fails because the receiver has been dropped, the error is logged but the peripheral is never removed from the map. Every subsequent advertisement packet from that peripheral repeats the same failing send and the same log line, for the lifetime of the adapter.Observed as a continuous flood of:
at sub-millisecond intervals.
Affected code
src/corebluetooth/internal.rsonmain, all following the same shape:on_manufacturer_data— error at L581on_service_data— error at L599on_services— error at L612on_services_modified— error at L629on_peripheral_disconnect(L807) and the handler at L919 share the pattern, though those are not advertisement-rate so they are far less visible.Why it matters
A dead receiver is terminal — nothing will ever read from that channel again — but the send is retried at advertisement rate, which during active scanning is every few milliseconds per peripheral. The cost is not just noise:
Reproduction
Drop the
Peripheralwhile the physical device is still advertising and scanning is still active. Concretely, in our case: stop the engine, change device configuration, restart the engine — the oldPeripheralobjects are dropped while CoreBluetooth keeps delivering adverts for the same UUIDs.Suggested fix
Treat a send error as terminal for that peripheral and drop it from the map, so at most one error is logged per peripheral:
Whether outright removal is correct depends on whether a peripheral is expected to be re-registered later by UUID; if so, clearing or replacing the sender would be the safer variant. Downgrading these particular sites from
error!todebug!/trace!would also help, since a dropped receiver is a normal consequence of the consumer going away rather than a fault.Environment
main