embedded_custom_transport_sketch
Transport trait. A
sketch, deliberately not wired into the running engine.
Source:
crates/dynomite/examples/embedded_custom_transport_sketch.rs
-- run with
cargo run -p dynomite --example embedded_custom_transport_sketch
What it demonstrates
Two things, and it is careful about what it does not claim:
- How to build an
AsyncRead + AsyncWrite + Send + Unpintype -- here, over atokio::io::DuplexStream-- which is the same pattern you use for a TLS stream, a Unix-domain socket, or a QUIC stream. - How that type implements
Transportby carrying aConnRoletag and reporting apeer_addr.
#![allow(unused)] fn main() { use dynomite::embed::{ConnRole, Transport}; pub struct PipeTransport { inner: tokio::io::DuplexStream, role: ConnRole, peer_addr: SocketAddr, } // impl AsyncRead / AsyncWrite by delegating to `inner`; // impl Transport by returning `role` and `peer_addr`. }
Why it is only a sketch
The example does not plug a custom listener into the
embedded engine. Wiring a Box<dyn TransportListener>
into ServerBuilder is deferred work; until it lands, the
embedded engine's sanctioned in-process entry point is
inject_request (see
embedded_cluster3). The
sketch shows the trait shape so that when the setter arrives, swapping
the built-in TcpListener for an embedder-supplied source is
a one-line change.
This honesty is itself a documentation decision: the example teaches the
trait contract without pretending a capability exists. It compiles and
runs (it exercises the PipeTransport end to end over the duplex
stream), so the trait implementation is real -- only the listener
integration is pending.
Design decisions and trade-offs
- DuplexStream as the byte source
- An in-memory pipe needs no OS resources and makes the example
hermetic. The same
AsyncRead + AsyncWritebound is what a real socket, TLS session, or QUIC stream satisfies, so the pattern transfers unchanged. - ConnRole tag on the transport
- A transport must say whether it carries client or peer traffic; that tag is how the engine routes a connection to the right handler.
Rather than a general plugin registry, Dynomite models a transport as a single trait an embedder implements and hands to the builder. The trait is small on purpose -- a byte stream plus a role and an address -- so that supporting a new transport is writing one adapter, not learning a framework. TCP and QUIC in the shipped engine are exactly such adapters.
When to use this pattern
When you need Dynomite to accept connections over something other than TCP or QUIC -- an in-process pipe for testing, a Unix socket, or a bespoke secure channel -- and you want to see the trait you will implement.
Where to go next
- Transports documents the built-in TCP and QUIC transports that implement this same trait.
- Hooks and Traits covers the other extension points.