Expand description
simu is a library for discrete-event simulation (DES), inspired by
Python’s SimPy but built to be idiomatic
Rust, fast, and reproducible.
Simulation processes are ordinary async blocks driven by a custom,
single-threaded executor over simulated time — there is no tokio/async-std
and no wall-clock waiting. Processes interact through timeouts, manual
events, and shared resources; the event queue is ordered by
(time, insertion) so a run is fully deterministic given the same seed and
logic.
New to simu? Start with the tutorial module — five short chapters
modeled on SimPy’s “SimPy in 10 minutes”, every snippet a running doc-test.
The crates.io package is named simu-des (the name simu was taken)
but the library target is simu: depend on simu-des = "0.1" and write
use simu::… exactly as in the examples here.
§Quick start
use simu::{SimEnv, Resource};
let mut env = SimEnv::with_seed(42);
let machine = Resource::new(1); // a pool of one unit, shared by cloning
let h = env.handle();
let m = machine.clone();
env.spawn(async move {
let _guard = m.request().await; // queue for the machine (FIFO)
h.timeout(2.0).await; // hold it for 2 simulated time units
}); // guard drops here → unit released
env.run(); // drive the event loop until the queue drains
assert_eq!(env.now(), 2.0);§Core types
| Type | Role |
|---|---|
SimEnv | Owns the event loop, current time, and the seeded RNG. Not Clone; one per thread. |
EnvHandle | Cheap Clone handle passed into processes: now / timeout / event / spawn / rng. |
Timeout | Future resolving after a simulated delay. |
EventTrigger / EventAwaitable | Manual inter-process signalling (multi-waiter, fire-before-await latch). |
Resource / ResourceGuard | FIFO capacity-limited pool; RAII release on guard drop. |
PriorityResource | Priority-scheduled pool (lower number = higher priority; FIFO within a level). |
PreemptiveResource / PreemptiveGuard | Priority pool whose in-use units can be preempted (cooperative-at-yield). |
Container | Reservoir of continuous quantity (put / get, strict head-of-line FIFO). |
ProcessHandle | Observable spawn: await for the return value, drop to detach. |
AnyOf / AllOf | Future combinators, built via the any_of! / all_of! macros. |
§Threading and Monte Carlo
SimEnv (and the resource handles) are !Send + !Sync — a simulation
lives entirely on one thread, which is why the executor needs no locking.
Parallelism comes from running independent simulations across threads:
monte_carlo::run executes a closure once per seed and returns the results
in seed order (one std::thread per seed by default; enable the
monte-carlo feature for a rayon-backed pool).
§Randomness
By default a SimEnv draws from rand’s StdRng. For cross-language
reproducibility, plug in a RandomSource via SimEnv::with_source — e.g.
the portable SplitMix64 feed, whose stream and the rng::sample
transforms are mirrored in Python for exact SimPy comparison.
§Feature flags
| Feature | Default | Effect |
|---|---|---|
monte-carlo | off | Switches monte_carlo::run from one-std::thread-per-seed to rayon’s bounded work-stealing pool — preferable for hundreds or thousands of seeds. |
§Examples
Four beginner examples (intro_car, intro_charging, intro_cancellation,
intro_charging_station) accompany the tutorial chapters. Three
end-to-end models combine everything: hospital (priority triage +
bed eviction + blood-bank Container), brewery (a bio-reactor production
line), and warehouse (a forklift fleet exercising PreemptiveResource).
Re-exports§
pub use rng::RandomSource;pub use rng::SplitMix64;
Modules§
- monte_
carlo - Monte Carlo helper: run a simulation closure once per seed, in parallel.
- rng
- Pluggable randomness sources and a portable, deterministic feed.
- tutorial
- simu in 10 minutes — a guided tour, one concept per chapter.
Macros§
- all_of
- Wait for all of several futures to resolve.
- any_of
- Wait for the first of several futures to resolve.
Structs§
- AllOf
- A future that resolves when all of its sub-futures have resolved.
- AnyOf
- A future that resolves when any one of its sub-futures resolves.
- Container
- A cloneable handle to a continuous-quantity resource (e.g., a tank of liquid, a battery, an inventory of medication).
- Container
GetRequest - Future returned by
Container::get. - Container
PutRequest - Future returned by
Container::put. - EnvHandle
- A lightweight handle to the simulation environment, intended to be cloned and passed into spawned processes.
- Event
Awaitable - The receiving half of a manual event.
- Event
Trigger - The sending half of a manual event. Call
fireto wake all processes currently waiting on the pairedEventAwaitable, and to make any future awaits on that same awaitable resolve immediately. - Preemptive
Guard - RAII guard holding one unit of a
PreemptiveResource. - Preemptive
Request - Future returned by
PreemptiveResource::request. - Preemptive
Resource - A cloneable handle to a capacity-limited pool whose held units can be preempted by higher-priority requests.
- Priority
Resource - A cloneable handle to a capacity-limited resource pool with priority scheduling.
- Priority
Resource Guard - RAII guard that holds one unit of a
PriorityResource. - Priority
Resource Request - Future returned by
PriorityResource::request. - Process
Handle - Handle to a spawned process. Resolves to the process’s return value.
- Resource
- A cloneable handle to a capacity-limited resource pool.
- Resource
Guard - RAII guard that holds one unit of a
Resource. - Resource
Request - Future returned by
Resource::request. - SimEnv
- The simulation environment. Central coordinator for a single simulation run.
- Timeout
- A
Futurethat resolves once simulated time reachesdeadline.