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
Warning
Not a runnable plug-in yet
The example does not plug a custom listener into the embedded engine. Wiring a
Box<dyn TransportListener>intoServerBuilderis deferred work; until it lands, the embedded engine’s sanctioned in-process entry point isinject_request(seeembedded_cluster3). The sketch shows the trait shape so that when the setter arrives, swapping the built-inTcpListenerfor 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.
Note
Road not taken: a transport-registry plugin system
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.