DesCartes is a Rust workspace for building deterministic, single-threaded discrete-event simulations (DES) of distributed and concurrent systems. It provides a stand-in replacement for core Rust libraries (tokio, tower, tonic, etc.) so that systems using these libraries can be simulated deterministically.
The core model contains:
- Core data structures to create components and tasks.
- Simulated time advances by processing scheduled events.
- Simulation is deterministic by default (given source of randomness) and traces are recorded and replayable.
- Async tasks (
async/await) run on a simulated runtime (descartes_tokio) backed by the DES scheduler. - Exploration tooling: systematic exploration of the state space via record/replay.
- Deterministic by default: given the same inputs/seeds, the simulation is reproducible.
- Single-threaded execution: concurrency is modeled via interleaving, not OS threads.
- No event priorities: same-time events are tie-broken deterministically (FIFO by default) with optional, seeded policies.
- Opt-in exploration: record/replay and randomized scheduling are explicit, seeded, and isolated from default runs.
- Tokio-like façade:
descartes_tokioprovides a subset of Tokio APIs backed by simulated time.
des-core: core simulation engine (scheduler, simulated time, async runtime integration, deterministic IDs, formal reasoning hooks)des-tokio: Tokio-like façade running ondes-core(tasks, time, channels, mutex/atomics, Semaphore/RwLock, JoinSet)des-explore: opt-in exploration tooling (trace record/replay, estimator utilities, replay validation)des-components: reusable components for distributed systems modeling (queues, servers, throttles, retry policies, etc.)des-tower: Tower integration for simulating real Tower middleware stacks deterministicallydes-tonic: tonic-like RPC façade built on simulated transport modelsdes-metrics: metrics collection and observability helpersdes-viz: visualization helpers for simulation outputs
Human-oriented overviews live in doc/human/.
Design notes and implementation details live in doc/ai/.
# Build all crates
cargo build
# Run all tests
cargo test
# Build rustdoc for the workspace
cargo doc --workspace --openAt the lowest layer (des-core), you schedule events and/or tasks, then run an executor.
use descartes_core::{Execute, Executor, Simulation, SimTime};
use std::time::Duration;
let mut sim = Simulation::default();
// Run the simulation for 1 simulated second.
Executor::timed(SimTime::from_duration(Duration::from_secs(1))).execute(&mut sim);For async workloads, install descartes_tokio into a simulation and spawn async tasks that use simulated time:
use descartes_core::{Execute, Executor, SimTime, Simulation};
use std::time::Duration;
let mut sim = Simulation::default();
descartes_tokio::runtime::install(&mut sim);
descartes_tokio::task::spawn(async {
descartes_tokio::time::sleep(Duration::from_millis(10)).await;
});
Executor::timed(SimTime::from_duration(Duration::from_millis(20))).execute(&mut sim);- Default ordering is FIFO at the DES scheduler frontier and within the async runtime.
- Any randomized policy must be explicitly installed and seeded.
This repository is licensed under Apache-2.0.
- Apache 2.0 text:
LICENSE-APACHE