The minimum library-use case for tsoracle: opens a FileDriver, builds a Server with sensible defaults, and serves gRPC. This is the example to start from when you want tsoracle running inside your own binary rather than as a separate tsoracle serve process.
The full walkthrough lives in Embedding the server; this README is the run-it-now quickstart.
cargo run -p example-embedded-serverThe server binds 127.0.0.1:50551 and persists state under ./tsoracle-embedded-data/. Ctrl-C drains in-flight RPCs and exits cleanly; any committed high-water extension was fsynced before the server handed out timestamps from that window.
Talk to it from another terminal with grpcurl:
grpcurl -plaintext -d '{"count":1}' 127.0.0.1:50551 tsoracle.v1.TsoService/GetTsOr from Rust using the tsoracle-client crate — see Calling tsoracle from Rust.
FileDriver::open_or_init(dir)is idempotent: the first run creates the state file, subsequent runs rehydrate from it.Server::builder().consensus_driver(driver).build()is the minimum required configuration.clock,window_ahead, andfailover_advanceget their defaults (3 s / 1 s).serve_with_shutdown(addr, future)drains in-flight RPCs when the shutdown future completes, then exits.
- You want HA. This example uses
FileDriver, which is single-node by design. Swap it for aConsensusDriverover your replicated log — seeexamples/openraft-standalone(own raft) orexamples/openraft-piggyback(shared raft) for worked versions. - You want to share a tonic listener with other services. Use
Server::into_routerinstead ofserve_with_shutdown; it returns aResultwrapping a tonicRoutesvalue plus aWatchGuardowning the leader-watch task (the outerResultsurfaces aServerError::ReflectionInitif the embedded descriptor set fails to decode under thereflectionfeature). Keep the guard alive for as long as the routes should serve, and drop it (or callshutdown().await) at your own shutdown to cooperatively stop the watch task;shutdown().awaitsurfaces any watch failure to your embedding process.