embedded_minimal
Source:
crates/dynomite/examples/embedded_minimal.rs --
run with cargo run -p dynomite --example embedded_minimal
What it demonstrates
The entire lifecycle of an embedded engine in the fewest possible calls: name a pool, bind two listeners, start, and shut down.
use dynomite::embed::{Server, ServerBuilder}; #[tokio::main(flavor = "current_thread")] async fn main() -> Result<(), Box<dyn std::error::Error>> { let handle = Server::start_with( ServerBuilder::new("dyn_o_mite") .listen("127.0.0.1:0".parse()?) .dyn_listen("127.0.0.1:0".parse()?), ) .await?; eprintln!( "embedded dynomite up; client listen={:?} dnode listen={:?}", handle.listen_addr(), handle.dyn_listen_addr() ); handle.shutdown().await?; Ok(()) }
Two listeners are the irreducible minimum: listen is the client-facing
port (where a Redis or Memcache client connects), and dyn_listen is the
DNODE peer plane (where other nodes connect). Binding to port 0 lets
the OS pick a free port, which you then read back with listen_addr()
and dyn_listen_addr() -- handy in tests.
Server::start_with is a convenience that builds and starts in one call.
The longer form -- ServerBuilder::...build()? then
server.start().await? -- is what
embedded_single_node uses, and it is what
you want when you need the Server value before it starts (for example,
to subscribe to its event stream).
Design decisions and trade-offs
- In-memory default backend
- With no
datastorehook and noservers, the engine uses the in-crate MemoryDatastore. That makes the example self-contained -- no Valkey to start -- at the cost of realism. The moment you want to front a real store you add one call; see the next example. - Gossip off by omission
- With no peers configured there is nothing to gossip with, so the example is effectively a single node. This keeps the output deterministic and the startup instant.
- current_thread runtime
- A single-threaded tokio runtime is enough for one node with no concurrent peer traffic and keeps the example's resource use trivial. Production embeddings use the multi-thread flavor.
ServerBuilder deliberately does not start the server when it is
built. Build and start are separate so that a caller can inspect or
register against the Server (events, stats handle) before any socket is
bound. start_with exists only to collapse the common case into one
line. See Server Lifecycle.
When to use this pattern
As a smoke test that the engine links and starts in your process, and as the skeleton you paste and then grow. It is not a useful deployment on its own -- it stores nothing durable and talks to no peers.
Where to go next
embedded_single_nodeadds a real Valkey backend and spells out the configuration.- Your First Embedded Engine walks this chain call by call.