#[cfg(feature = "visualize")]
use sids::actors::actor::Actor;
#[cfg(feature = "visualize")]
use sids::actors::messages::Message;
#[cfg(feature = "visualize")]
use sids::actors::response_handler::from_oneshot;
#[cfg(feature = "visualize")]
use sids::actors::{
messages::ResponseMessage, send_message_by_id, spawn_actor, start_actor_system_with_config,
};
#[cfg(feature = "visualize")]
use sids::config::SidsConfig;
#[cfg(feature = "visualize")]
use sids::supervision_export::{to_dot, to_json, to_mermaid, to_mermaid_sequence, to_text_summary};
#[cfg(feature = "visualize")]
struct RequestActor;
#[cfg(feature = "visualize")]
impl Actor<String, ResponseMessage> for RequestActor {
async fn receive(&mut self, message: Message<String, ResponseMessage>) {
if let Some(payload) = message.payload {
println!("RequestActor received: {}", payload);
}
if let Some(responder) = message.responder {
responder.handle(ResponseMessage::Success).await;
}
}
}
#[cfg(feature = "visualize")]
struct WorkerActor;
#[cfg(feature = "visualize")]
impl Actor<String, ResponseMessage> for WorkerActor {
async fn receive(&mut self, message: Message<String, ResponseMessage>) {
if let Some(payload) = message.payload {
println!("WorkerActor processing: {}", payload);
}
if let Some(responder) = message.responder {
responder.handle(ResponseMessage::Success).await;
}
}
}
#[cfg(feature = "visualize")]
struct CoordinatorActor;
#[cfg(feature = "visualize")]
impl Actor<String, ResponseMessage> for CoordinatorActor {
async fn receive(&mut self, message: Message<String, ResponseMessage>) {
if let Some(payload) = message.payload {
println!("CoordinatorActor coordinating: {}", payload);
}
if let Some(responder) = message.responder {
responder.handle(ResponseMessage::Success).await;
}
}
}
#[tokio::main]
async fn main() {
#[cfg(not(feature = "visualize"))]
{
println!("This example requires the 'visualize' feature.");
println!("Run with: cargo run --example supervision --features visualize");
return;
}
#[cfg(feature = "visualize")]
{
if let Err(e) = run_supervision_demo().await {
eprintln!("Supervision demo failed: {}", e);
std::process::exit(1);
}
}
}
#[cfg(feature = "visualize")]
async fn run_supervision_demo() -> Result<(), Box<dyn std::error::Error>> {
println!("=== SIDS Supervision System Example ===\n");
let config = SidsConfig::default();
let mut actor_system = start_actor_system_with_config::<String, ResponseMessage>(config);
println!("Spawning actors...");
spawn_actor(
&mut actor_system,
RequestActor,
Some("RequestActor".to_string()),
)
.await;
spawn_actor(
&mut actor_system,
WorkerActor,
Some("WorkerActor".to_string()),
)
.await;
spawn_actor(
&mut actor_system,
CoordinatorActor,
Some("CoordinatorActor".to_string()),
)
.await;
println!("Actors spawned!\n");
println!("Sending messages between actors...");
let (tx, rx) = tokio::sync::oneshot::channel();
let handler = from_oneshot(tx);
let msg = sids::actors::messages::Message {
payload: Some("Process this request".to_string()),
stop: false,
responder: Some(handler),
blocking: None,
};
send_message_by_id(&mut actor_system, 1, msg).await?;
let _ = rx.await;
actor_system.record_message_sent(0, 1);
let (tx, rx) = tokio::sync::oneshot::channel();
let handler = from_oneshot(tx);
let msg = sids::actors::messages::Message {
payload: Some("Task completed".to_string()),
stop: false,
responder: Some(handler),
blocking: None,
};
send_message_by_id(&mut actor_system, 2, msg).await?;
let _ = rx.await;
actor_system.record_message_sent(1, 2);
let (tx, rx) = tokio::sync::oneshot::channel();
let handler = from_oneshot(tx);
let msg = sids::actors::messages::Message {
payload: Some("All done, results ready".to_string()),
stop: false,
responder: Some(handler),
blocking: None,
};
send_message_by_id(&mut actor_system, 0, msg).await?;
let _ = rx.await;
actor_system.record_message_sent(2, 0);
for i in 0..3 {
let (tx, rx) = tokio::sync::oneshot::channel();
let handler = from_oneshot(tx);
let msg = sids::actors::messages::Message {
payload: Some(format!("Message {} from RequestActor", i)),
stop: false,
responder: Some(handler),
blocking: None,
};
send_message_by_id(&mut actor_system, 1, msg).await?;
let _ = rx.await;
actor_system.record_message_sent(0, 1);
}
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
println!("Messages sent!\n");
let supervision = actor_system.get_supervision_data();
let _summary = actor_system.get_supervision_summary();
println!("{}", to_text_summary(&supervision));
println!();
match to_json(&supervision) {
Ok(json) => {
println!("=== JSON Export ===");
println!("{}\n", json);
}
Err(e) => {
eprintln!("Failed to export JSON: {}", e);
}
}
let dot = to_dot(&supervision);
println!("=== Graphviz DOT Export ===");
println!("{}", dot);
println!("To visualize this, save to a .dot file and run: dot -Tsvg graph.dot -o graph.svg\n");
let mermaid = to_mermaid(&supervision);
println!("=== Mermaid Diagram Export ===");
println!("{}", mermaid);
println!("Paste the above into https://mermaid.live to visualize\n");
let sequence = to_mermaid_sequence(&supervision);
println!("=== Mermaid Sequence Diagram Export ===");
println!("{}", sequence);
println!("Paste the above into https://mermaid.live to visualize the message flow\n");
actor_system.shutdown().await?;
println!("Actor system shut down cleanly.");
Ok(())
}