sprite-core 0.1.5

Sprite Engine — a fault-tolerant actor runtime for Rust
Documentation

SpriteEngine Logo

On Crates


⚡ What is Sprite?

Sprite is a Rust library for building fault-tolerant, concurrent actor systems with a clean, declarative API inspired by React.

Instead of writing complex supervision trees and manual error handling, you write actor components — pure setup closures that declare state, message handlers, and children. If an actor panics, Sprite automatically resurrects it in under 50 nanoseconds with its state intact.


🚀 Quick Start

use sprite_core::{Engine, Message};

fn main() {
    let engine = Engine::new();

    let counter = engine.spawn("counter", |ctx| {
        // Like React's useState — survives crashes
        let count = ctx.use_state("count", 0i64);

        ctx.on_message(move |msg| {
            if msg == "inc" {
                count.update(|c| c + 1);
                println!("count = {}", count.get());
            }
        });
    });

    counter.send(Message::text("inc"));
    counter.send(Message::text("inc"));
}

🧩 Core Concepts

Concept React Equivalent What it does
Engine createRoot The runtime that mounts and manages actors
engine.spawn(name, |ctx| { ... }) <Component /> Creates an actor from a setup closure
ctx.use_state(key, initial) useState Declares typed state that survives crashes
ctx.use_scratch(initial) useRef Ephemeral value wiped on recovery
ctx.on_message(|msg| { ... }) onClick / event handler Registers a message handler
ctx.on_panic(| | { ... }) componentDidCatch Runs after each panic recovery
ctx.on_mount(| | { ... }) useEffect([], ...) Runs once on first start
ctx.on_unmount(| | { ... }) cleanup function Runs on graceful shutdown
ctx.spawn(name, ...) child components Spawns nested actors
ctx.send_to(id, msg) props callback Sends a message to another actor
ctx.send_named(name, msg) Sends to a named actor
ctx.poll() Non-blocking message check
ctx.sleep(dur) Yield without blocking thread
Handle::send(msg) setState / props Sends a message to an actor
Handle::send_msg(any) Send any IntoMessage type
Handle::request(msg, timeout) fetch Request/response pattern

🔥 Fault Tolerance

     [ Panic in Actor ]
           │
           ▼
   catch_unwind catches it     (~0.05ms)
           │
           ▼
   Arena reset                  (~1ns)
           │
           ▼
   State already intact         (0ns — lives in shared store)
           │
           ▼
   Setup closure re-runs        (~1ms)
           │
           ▼
   Actor Fully Restored         (< 50ns for recovery core)

State created via use_state lives in a shared store outside the actor thread, so it survives panics automatically. The actor's scratch allocations (via bumpalo) are reset, but your data is safe.


🛡️ Circuit Breaker

If an actor panics more than 10 times in 5 seconds, Sprite trips a circuit breaker and halts it — preventing infinite crash loops.

engine.spawn("fragile", |ctx| {
    ctx.on_message(|_| panic!("always"));
    // After 10 recoveries, this actor stops.
});

📦 Installation

[dependencies]
sprite-core = { git = "https://github.com/dragprog/sprite-engine" }

🏗️ Advanced Examples

Actor Pool (load balancing)

use sprite_core::{Engine, Message, Pool};

let engine = Engine::new();
let pool = Pool::new(&engine, "worker", 4, |ctx| {
    ctx.on_message(|task| {
        println!("Worker {} processing: {:?}", ctx.id(), task);
    });
});

for i in 0..100 {
    pool.send(Message::int(i));
}

Broadcast

engine.broadcast(Message::text("shutdown"));

Named Actors

engine.spawn("logger", |ctx| {
    ctx.on_message(|msg| println!("{:?}", msg));
});

engine.send_named("logger", Message::text("hello"));
assert_eq!(engine.lookup("logger"), Some(id));

Timer

use sprite_core::Timer;
use std::time::Duration;

Timer::send_after(handle.tx.clone(), Duration::from_secs(5), Message::text("timeout"));

Builder API

use sprite_core::{Engine, ActorBuilder};

let handle = ActorBuilder::new("worker", |ctx| {
    ctx.on_message(|msg| { /* ... */ });
})
.arena_size(1024 * 128)
.max_recoveries(5)
.recovery_window(Duration::from_secs(10))
.spawn(&engine);

🧪 Running Tests

git clone https://github.com/dragprog/sprite-engine.git
cd sprite-engine
cargo test --workspace
cargo bench --bench recovery_speed
cargo bench --bench mailbox_throughput
cargo run --example counter
cargo run --example pool
cargo run --example broadcast

📊 Benchmarks

Benchmark Target
recovery_speed Panic → full restore
mailbox_throughput Messages / second

🤝 Contributing

  1. Fork the repo (git checkout -b feature/cool-thing).
  2. Keep the API surface minimal and ergonomic.
  3. Ensure tests pass (cargo test).
  4. Submit a PR with a concise breakdown.

📄 License

Distributed under the Apache License 2.0. See LICENSE for details.