Skip to content

Feat/platform agnostic tcp connectors - #250

Open
lxsaah wants to merge 4 commits into
mainfrom
feat/platform-agnostic-connectors
Open

Feat/platform agnostic tcp connectors#250
lxsaah wants to merge 4 commits into
mainfrom
feat/platform-agnostic-connectors

Conversation

@lxsaah

@lxsaah lxsaah commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Wave B of design 052, first connector: the TCP connector moves onto the runtime-neutral I/O layer wave A added. The adapter owns the socket; this crate contributes only length-prefix framing.

The crate goes from 1 428 lines to 385.

Commits

add generic TcpClient/TcpServer over StreamDialer/StreamListener; the runtime modules stay
migrate tests and tcp_demo onto the adapter transports; the old modules become unreferenced
delete tokio_transport.rs (302) + embassy_transport.rs (591), and the dependencies they needed

Split that way so the deletion diff is purely subtractive and every commit is green on its own.

Result

  • Zero unsafe impls in any connector crate — the three here were the last outside the adapters (acceptance 2).
  • No tokio, embassy-net, embassy-futures or embedded-io-async in the library graph — checked with cargo tree, not just by deleting files (acceptance 3). embassy-net remains test-only for the loopback harness.

Breaking

lib.rs's whole all(tokio-runtime, embassy-runtime) aliasing block is gone — TokioTcpServer/EmbassyTcpServer, TokioTcpConnection/EmbassyTcpConnection and friends existed only to disambiguate two implementations of the same concept. One implementation, one name:

pub use connector::{framed_dialer, framed_dialer_at, framed_listener, split_host_port,
                    TcpClient, TcpServer, DEFAULT_PORT};

TcpServer::new now takes an already-bound listener rather than a bind string, so the adapter does the binding.

Worth a look in review

Framer::encode is infallible, but length-prefix encoding is not. An oversized frame is dropped whole rather than written half-encoded — a length prefix with no payload behind it would desync the peer permanently, and unlike COBS there is no delimiter to resync on.

TcpServer holds its listener in a OneShot, taken on first poll rather than at call time. A build() future dropped before being polled must leave the listener in place, or a later build fails having never served anything. an_unpolled_build_leaves_the_listener_in_place pins it.

split_host_port fixes a bug it inherited. Two call sites had grown private copies using rsplit_once(':'), which mangles a bracketed IPv6 host with no port — the form aimdb-client's own error message documents. Hoisted into the connector with five tests; brackets are now stripped, which is what both adapters actually resolve.

Verification

make check clean: 2 031 tests, 0 failures, all stages. aimdb-client needed a fix — it used the deleted TcpDialer through the crate-root re-export, which a module-path grep does not see.

- Updated `Cargo.toml` and `Cargo.lock` to remove unnecessary dependencies and streamline the project.
- Modified `endpoint.rs` to utilize the new `framed_dialer_at` function for TCP connections.
- Enhanced `connector.rs` with a new `split_host_port` function to handle host:port parsing and added a `framed_dialer_at` function for cleaner dialing.
- Removed the `embassy_transport.rs` and `tokio_transport.rs` files as they are superseded by the new connector implementation.
- Updated `lib.rs` to reflect the changes in module structure and removed deprecated transport modules.
- Adjusted example in `tcp_demo.rs` to align with the new dialing approach.
@lxsaah lxsaah changed the title Feat/platform agnostic connectors Feat/platform agnostic tcp connectors Sep 6, 2026
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant