M17 centralize embassy connector spines#128
Merged
Merged
Conversation
- Updated documentation in `lib.rs` to clarify the role of `aimdb-embassy-adapter` in handling `Send` and `unsafe` plumbing. - Modified `embassy_smoke.rs` test to utilize `CobsFramer` and `OneShotDialer` for a more accurate representation of the connection model. - Added a temporary ignore for `RUSTSEC-2026-0173` in `deny.toml` due to unmaintained dependencies. - Revised the Embassy implementation pattern in the development guide to emphasize the centralized adapter spine approach and remove unnecessary boilerplate. - Introduced a new design document outlining the unification of Embassy connectors, focusing on the centralized adapter spine and the removal of `Send` from the connector contract.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the M17 milestone: every Embassy connector used to hand-roll the same force-
Sendbridge between AimDB'sSend-everywhere connector contract and Embassy's deliberately!Sendprimitives. That plumbing — and all of the single-coreunsafe— now lives once, audited, inaimdb-embassy-adapter::connectors. The connector crates carry zerounsafeand zeroSendFutureWrapperuse.What changed
aimdb-embassy-adapter— newconnectorsmodule (featuresconnectors/connector-io)The one home for the safety invariant (single-core, cooperative Embassy executor — no preemption, no thread migration; every
unsafe implcites it). Gated tono_stdbuilds so the force-Sendtypes can't leak into std/Tokio code.EmbassySessionClient/EmbassySessionServer(Embassy duals of core'sSessionClientConnector/SessionServerConnector),OneShotDialer/OneShotListenerover a moved-in peripheral connection (the listener parks forever after the first accept — point-to-point), and the force-Send + SyncOneShotCellfor builders holding a moved-in value.connector-io) —EmbassyConnection<Rd, Wr, F>overembedded-io-asyncRead/Writehalves with a pluggableFramer; chunks writes for atomic-or-error HALBufferedUarts and skip-and-resyncs on undecodable runs.EmbassySinkRaw/EmbassySourceRaw(the!Sendduals of core'sConnector/Source) with force-SendEmbassySink/EmbassySourcewrappers, so an Embassy connector rides core's existingpump_sink/pump_sourceunchanged;into_box_futurefor long-lived!Sendprotocol tasks.EmbassySessionClient::newdefaults toreconnect: false(unlikeClientConfig::default): a one-shot dialer can't redial, so the engine would otherwise spin onTransportError::Ioforever. A re-dialable transport opts back in viawith_config.aimdb-serial-connector(Embassy half)Now thin sugar over the spine: this crate contributes only the COBS
CobsFramer. Down from a 407-line hand-roll with 7unsafe impls to 0. The Embassy half is structurally a sibling of the Tokio half — both thin sugar over a shared spine.SerialClient::new(rx, tx)returns the spine'sEmbassySessionClient;SerialServerstores the moved-in framed connection in aOneShotCelland drivesserve.aimdb-mqtt-connector(Embassy half)The hand-rolled outbound publisher and inbound event-router loops are gone; the data-flow rides core's
pump_sink/pump_sourcethrough the adapter bridges, exactly like the Tokio half. This crate contributes only the broker manager task (mountain-mqtt'srun) and theMqttSink/MqttSourceover its action/event channels. Per-routeqos/retainstill arrive from the link URL query (now viaConnectorConfig::protocol_options).aimdb-knx-connector(Embassy half)This crate now contributes only the KNX/IP protocol (UDP socket + tunnelling state machine, force-
Sended once viainto_box_future). Outbound ridespump_sinkthrough the existingConnectorimpl; inbound telegrams now flow throughpump_sourcevia a new static 32-deep telegram channel.Docs
docs/design/033-M17-unify-connectors-drop-send.md(audit, key insight, the superseding Implementation Decision).docs/design/012-M5-connector-development-guide.mdrewritten for the spine: "do not hand-roll theunsafe/force-Sendbridge", with the session-transport and data-plane recipes.Behavior changes (intentional, documented in the crate changelogs)
PublishError::InvalidDestination, logged) instead of silently falling back to the URL's default address — the fallback was misrouting (writing a different group address than the provider asked for), and dropping matches the Tokio half.try_sendand drops + logs when the 32-deep channel is full, rather than routing inline. A slow consumer can never stall the loop that answersTUNNELING_ACKs and heartbeats — a stalled loop would time out the gateway tunnel and lose far more than one telegram. (The router already dropped on full producer buffers; this moves the bounded loss point earlier.)defmtcalls into core'spump_source(tracingfeature), so defmt-only MCU builds no longer log per-message routing failures.Breaking changes
MqttConnectorImpl(Embassy, waspub) removed; its logic collapsed into the builder'sbuild(). Registration viaMqttConnectorBuilderis unchanged.EmbassySerialConnection/SerialDialer/SerialListenerreplaced by the spine'sEmbassyConnection/OneShotDialer/OneShotListener;SerialClient::newnow returns the spine connector (the.scheme(...)/.with_config(...)chaining is unchanged). All crates are pre-1.0 / unreleased entries.Housekeeping
.cargo/audit.toml: dropped theRUSTSEC-2026-0049ignore —rustls-webpkiis now at 0.103.x, the advisory no longer applies.deny.toml: temporary ignore forRUSTSEC-2026-0173(proc-macro-error2unmaintained, transitive viadefmt-macros/tabled_derive)._external/embassysubmodule fast-forwarded 18 upstream commits (with the matchingstm32-metapacretag inCargo.lock).Testing
aimdb-embassy-adapter/tests/connectors_smoke.rs):OneShotCelltake-once semantics,OneShotListenerparking forever after the first accept, and core'sservedispatching over the one-shot listener then staying alive on the parked accept. Wired intomake test(adapter host tests now run withconnectors).OneShotDialer<EmbassyConnection<_, _, CobsFramer>>).make embedded-checkline: adapter withembassy-runtime,connector-ioonthumbv7em-none-eabihf.thumbv7em-none-eabihf(incl.defmtvariants); all three Embassy demos (serial on STM32H563ZI, MQTT, KNX) build; clippy clean with-D warningson the changed configurations.