tsoracle-server 0.1.0

Embeddable gRPC server for the timestamp oracle.
Documentation

Crates.io docs.rs DeepWiki guide CI Coverage Status License Crates.io

A standalone timestamp oracle for Rust — strictly monotonic, gap-free integer timestamps over gRPC, with pluggable consensus.

Features

  • 🔢 Monotonic & gap-free — every issued timestamp is strictly greater than the last; no skipped or repeated values, ever.
  • 🛡️ Crash-safe — window state is fsync'd before any timestamp in that window is handed out, so a restart never rewinds.
  • 🔌 Pluggable consensus — implement one trait (ConsensusDriver) to plug in openraft, raft-rs, etcd, or your own replicated log.
  • 📦 gRPC client includedtsoracle-client handles leader discovery, request coalescing, and reconnection for you.
  • 🧩 Embeddable — host the server inside your own binary with a few lines of Rust, or run the standalone CLI.

Quickstart

Install the standalone binary and start the server:

cargo install tsoracle
tsoracle serve

The server listens on 127.0.0.1:50551 and persists state under ./tsoracle-data/.

Then call it from Rust:

use tsoracle_client::Client;

let client = Client::connect(vec!["http://127.0.0.1:50551".into()]).await?;

let ts = client.get_ts().await?;             // a strictly increasing Timestamp
let batch = client.get_ts_batch(64).await?;  // amortize RPC cost across many IDs

Use as a library

Embed the server in your own binary instead of running the CLI:

use tsoracle_server::Server;
use tsoracle_driver_file::FileDriver;

let driver = FileDriver::open_or_init("./tsoracle-data")?;
let server = Server::builder()
    .consensus_driver(driver)
    .build()?;

server
    .serve_with_shutdown("127.0.0.1:50551".parse()?, async {
        let _ = tokio::signal::ctrl_c().await;
    })
    .await?;

A complete, runnable version lives in examples/embedded-server. Want to mount tsoracle inside an existing tonic server? See Server::into_router.

What's a TSO?

A timestamp oracle is a service that hands out strictly increasing integer IDs which order events across a distributed system. You reach for one when:

  • You're building a database with snapshot isolation or MVCC (Spanner, TiDB, CockroachDB, FoundationDB all use a TSO internally).
  • You need to merge change-data from many shards into one globally ordered stream.
  • You want audit logs with a real "happens-before" relation across machines.
  • Per-host clocks aren't monotonic or accurate enough, and database sequences don't scale to your workload.

tsoracle is a small, embeddable Rust implementation. The consensus layer is left as a trait, so you can run it single-node behind one fsync (the default), or wire it into a replicated log of your choice.

Documentation

  • DeepWiki — prose documentation covering the window allocator, the ConsensusDriver contract, and operational topics (fsync cost, leader handoff, deployment topologies).
  • docs.rs/tsoracle-server — generated API reference.

Examples

  • examples/embedded-server — embed tsoracle-server with the file driver in your own binary, with graceful shutdown.
  • examples/failover-demo — pedagogy: watch the failover fence keep timestamps strictly monotonic across simulated leadership changes, in-process, no openraft.
  • examples/openraft-cluster — full HA: ConsensusDriver implemented over openraft, 3-node multi-process cluster with file-backed log and state.

Each example is its own crate. Build with cargo run -p example-<name>.

Contributing

Issues and pull requests are welcome. See CONTRIBUTING.md for local setup, the checks CI will run on your PR, commit message conventions, and the release process.

License

Licensed under Apache-2.0.