byteflow-actors
Byteflow is a small, embeddable flow runtime for Rust: register-based bytecode, lightweight flows, Atomic Hop messaging (Value::Message only on Send), cooperative scheduling, and a one-for-one supervisor — without a separate scripting language.
You assemble programs with ChunkBuilder in host Rust. The host owns I/O; Byteflow owns cheap concurrency.
Package name:
byteflow-actorson crates.io
Rust import:use byteflow::...(the library crate is namedbyteflow)
Why this exists
Use Byteflow when you need many isolated units of work that talk through messages, share a handful of OS threads, and can fail without taking the worker down:
- plugin / rule / workflow engines inside a larger binary
- simulations and game logic (not the render loop)
- sandboxed “virtual processes” with a host-defined FFI table
It is not a Tokio replacement, not a distributed cluster, and not a JVM.
Install
[]
= "0.5"
use ;
CLI (same package):
cargo install byteflow-actors
byteflow demo ping-pong
Quick start
use ;
Std natives (print, now_ms, make_msg, …)
Stable indices: print = 0, now_ms = 1, make_msg = 2, msg_* = 3–6, msg_reply_cap = 7.
use ;
Or std_natives() → (NativeTable, HashMap<name, index>) so host registration stays aligned with bytecode.
Messaging (Atomic Hop)
Every Send carries one Value::Message envelope (scalars trap):
cargo run --example ping_pong
cargo run --example atomic_actors
# optional scheduler logs on stderr:
# BYTEFLOW_LOG=info cargo run --example atomic_actors
See docs/atomic-hop.md. Built-in samples:
byteflow::samples::{ping_pong, atomic_request_reply, add_forty_two, boom}.
Architecture
| Layer | Responsibility |
|---|---|
| Bytecode | ISA, ChunkBuilder, BFV0 (.bf) encode/decode, static verify |
| VM | One flow: registers, call stack, cooperative quantum, CallNative |
| Scheduler | M:N workers, FIFO mailboxes (park/wake), timer, supervisor |
| Facade | Public API + std natives + samples + byteflow CLI |
Flow lifecycle (sketch):
- Worker runs at most
quantuminstructions (default 10 000). Yield/ budget → run queue (stealable).Sleep→ timer thread → injector.- Empty
Receive→ flow parks inside its mailbox; the next Atomic Hop wakes under the same lock (no lost wakeup). Fault/Trap→FlowState::Failed→ supervisor (Always/OnFailure/Never; default intensity 3 / 5s).
join() is for the embedder’s native thread only — workers never block on it.
Untrusted .bf files go through Opcode::from_u8 + verify before execution.
CLI
byteflow demo [ping-pong|atomic|add]
byteflow pack <demo> <out.bf>
byteflow verify <file.bf>
byteflow disasm <file.bf>
byteflow run <file.bf> [function]
run and hop demos attach the std native table (print, now_ms, make_msg, msg_*).
Safety & design notes
#![forbid(unsafe_code)]- Flow panics are caught at the worker boundary so one bad flow cannot kill the OS thread.
- Native functions must not block — they run inline on a worker.
- Host APIs return
Result(SpawnError/RuntimeError) — nounwrap/expecton production paths (seedocs/error-model.md). - Values today:
Unit | Bool | Int | Float | Pid | Message | Cap | Str | Bytes. - Atomic Hop: only
Value::Messagemay crossSend. - FlowCap: bytecode
Send/Asktargets areValue::Cap; replies usemsg_reply_cap. - Security: authenticated hop sender + FlowCap — see
docs/security.md.
Status (v0.5)
Included: register ISA + assembler, BFV0 (ABI v4 / Message + Cap + Str/Bytes), verifier, per-flow VM, M:N scheduler, mailboxes, Atomic Hop, FlowCap, supervisor, std natives, CLI, examples, fail-closed error model.
Not yet: bounded mailboxes, Criterion benches, timing wheel, JIT, distribution.
See CHANGELOG.md.
Links
- Repository: github.com/mchael158/bytecode-vm
- Docs: docs.rs/byteflow-actors
- License: MIT OR Apache-2.0