mesh_architecture/
mesh_architecture.rs

1use async_trait::async_trait;
2use ceylon_runtime::core::agent::{Agent, AgentContext};
3use ceylon_runtime::core::error::Result;
4use ceylon_runtime::core::mesh::Mesh;
5use ceylon_runtime::core::message::Message;
6use ceylon_runtime::local::LocalMesh;
7use std::sync::Arc;
8use std::time::Duration;
9use tokio::sync::Notify;
10
11// --- Worker Agent ---
12struct WorkerAgent {
13    mesh: Arc<LocalMesh>,
14}
15
16#[async_trait]
17impl Agent for WorkerAgent {
18    fn name(&self) -> String {
19        "worker".to_string()
20    }
21
22    async fn on_start(&mut self, _ctx: &mut AgentContext) -> Result<()> {
23        println!("[Worker] Started and ready for tasks.");
24        Ok(())
25    }
26
27    async fn on_message(&mut self, msg: Message, _ctx: &mut AgentContext) -> Result<()> {
28        let content = String::from_utf8_lossy(&msg.payload);
29        println!("[Worker] Received task from {}: {}", msg.sender, content);
30
31        // Simulate processing
32        tokio::time::sleep(Duration::from_millis(500)).await;
33
34        // Send response
35        let response = format!("Processed: {}", content);
36        println!("[Worker] Sending response: {}", response);
37
38        let reply_msg = Message::new("result", response.into_bytes(), self.name());
39        self.mesh.send(reply_msg, &msg.sender).await?;
40
41        Ok(())
42    }
43}
44
45// --- Manager Agent ---
46struct ManagerAgent {
47    mesh: Arc<LocalMesh>,
48    completion_notify: Arc<Notify>,
49}
50
51#[async_trait]
52impl Agent for ManagerAgent {
53    fn name(&self) -> String {
54        "manager".to_string()
55    }
56
57    async fn on_start(&mut self, _ctx: &mut AgentContext) -> Result<()> {
58        println!("[Manager] Started. Sending task to worker...");
59
60        // Send a task to the worker
61        let task_msg = Message::new("task", b"Analyze data".to_vec(), self.name());
62        self.mesh.send(task_msg, "worker").await?;
63
64        Ok(())
65    }
66
67    async fn on_message(&mut self, msg: Message, _ctx: &mut AgentContext) -> Result<()> {
68        let content = String::from_utf8_lossy(&msg.payload);
69        println!("[Manager] Received result from {}: {}", msg.sender, content);
70
71        // Signal completion
72        self.completion_notify.notify_one();
73        Ok(())
74    }
75}
76
77#[tokio::main]
78async fn main() -> Result<()> {
79    // 1. Create the Mesh (wrapped in Arc for sharing)
80    let mesh = Arc::new(LocalMesh::new("main_mesh"));
81
82    // 2. Create Agents with reference to mesh
83    let completion = Arc::new(Notify::new());
84
85    let worker = Box::new(WorkerAgent { mesh: mesh.clone() });
86    let manager = Box::new(ManagerAgent {
87        mesh: mesh.clone(),
88        completion_notify: completion.clone(),
89    });
90
91    // 3. Register Agents
92    mesh.add_agent(worker).await?;
93    mesh.add_agent(manager).await?;
94
95    // 4. Start Mesh
96    mesh.start().await?;
97
98    // Wait for the interaction to complete
99    println!("Waiting for interaction to complete...");
100    // Timeout after 5 seconds
101    tokio::select! {
102        _ = completion.notified() => {
103            println!("Interaction completed successfully!");
104        }
105        _ = tokio::time::sleep(Duration::from_secs(5)) => {
106            println!("Timeout waiting for interaction.");
107        }
108    }
109
110    // 5. Stop Mesh
111    mesh.stop().await?;
112
113    Ok(())
114}