Skip to main content

atomic_actors/
atomic_actors.rs

1//! Atomic Hop: one [`byteflow::Value::Message`] per request/reply hop.
2//!
3//! This is the runnable counterpart of `samples::atomic_request_reply` and
4//! `docs/atomic-hop.md`. It wires the std native table (needed for
5//! `make_msg` / `msg_*` / `print`) and joins until the client returns
6//! payload `42`.
7//!
8//! ```text
9//! cargo run -p byteflow-actors --example atomic_actors
10//!
11//! # scheduler stderr (spawn/send/recv/finish) — separate from print's stdout
12//! $env:BYTEFLOW_LOG="info"
13//! cargo run -p byteflow-actors --example atomic_actors
14//! ```
15//!
16//! Failures from `Runtime::…` / `spawn` are printed and exit non-zero —
17//! matching the fail-closed host API (no `.expect` on the happy path).
18
19use byteflow::{samples, std_native_table, FlowOutcome, Runtime, RuntimeConfig, Value};
20
21fn main() {
22    let chunk = samples::atomic_request_reply();
23    let rt = match Runtime::with_natives_and_config(
24        chunk,
25        std_native_table(),
26        RuntimeConfig {
27            workers: 2,
28            quantum: 10_000,
29        },
30    ) {
31        Ok(rt) => rt,
32        Err(e) => {
33            eprintln!("runtime: {e}");
34            std::process::exit(1);
35        }
36    };
37    let Some(main) = rt.function_index("main") else {
38        eprintln!("missing main");
39        std::process::exit(1);
40    };
41    let handle = match rt.spawn(main, &[]) {
42        Ok(h) => h,
43        Err(e) => {
44            eprintln!("spawn: {e}");
45            std::process::exit(1);
46        }
47    };
48    let outcome = handle.join();
49    let metrics = rt.metrics();
50    rt.shutdown();
51
52    match outcome {
53        FlowOutcome::Completed(Value::Int(42)) => {
54            println!("atomic request-reply ok: payload=42");
55            println!("{metrics}");
56        }
57        other => {
58            eprintln!("unexpected {other:?}");
59            std::process::exit(1);
60        }
61    }
62}