| 
 | 1 | +//! # Example: recv_any_example  | 
 | 2 | +//! Demonstrates how to use the `recv_any` method of `InChannels` to receive data from any available channel.  | 
 | 3 | +//!  | 
 | 4 | +//!  | 
 | 5 | +//! # Output  | 
 | 6 | +//! When running this example, you will see output similar to:  | 
 | 7 | +//! ```  | 
 | 8 | +//! Received message 'Hello from Sender' from node NodeId(1)  | 
 | 9 | +//! Received message 'Hello from SlowSender' from node NodeId(2)  | 
 | 10 | +//! ```  | 
 | 11 | +//!  | 
 | 12 | +//! The first message comes from the normal sender, and the second message comes from the slow sender  | 
 | 13 | +//! after a 500ms delay.  | 
 | 14 | +//!  | 
 | 15 | +//! //! This example creates a graph with two senders and one receiver:  | 
 | 16 | +//! - A normal sender that sends messages immediately  | 
 | 17 | +//! - A slow sender that delays 500ms before sending messages  | 
 | 18 | +//! - A receiver that uses `recv_any` to receive messages from either sender  | 
 | 19 | +//!  | 
 | 20 | +//! # Output  | 
 | 21 | +//! When running this example, you will see output similar to:  | 
 | 22 | +//! ```  | 
 | 23 | +//! Received message 'Hello from Sender' from node NodeId(1)  | 
 | 24 | +//! Received message 'Hello from SlowSender' from node NodeId(2)  | 
 | 25 | +//! ```  | 
 | 26 | +//!  | 
 | 27 | +//! The first message comes from the normal sender, and the second message comes from the slow sender  | 
 | 28 | +//! after a 500ms delay.  | 
 | 29 | +
  | 
 | 30 | +use std::{sync::Arc, time::Duration};  | 
 | 31 | + | 
 | 32 | +use async_trait::async_trait;  | 
 | 33 | +use dagrs::{  | 
 | 34 | +    connection::{in_channel::TypedInChannels, out_channel::TypedOutChannels},  | 
 | 35 | +    node::typed_action::TypedAction,  | 
 | 36 | +    DefaultNode, EnvVar, Graph, Node, NodeTable, Output,  | 
 | 37 | +};  | 
 | 38 | +use tokio::time::sleep;  | 
 | 39 | + | 
 | 40 | +/// An action that sends a message to its output channel  | 
 | 41 | +#[derive(Default)]  | 
 | 42 | +pub struct SenderAction {  | 
 | 43 | +    message: String,  | 
 | 44 | +}  | 
 | 45 | + | 
 | 46 | +impl SenderAction {  | 
 | 47 | +    pub fn new(message: String) -> Self {  | 
 | 48 | +        Self { message }  | 
 | 49 | +    }  | 
 | 50 | +}  | 
 | 51 | + | 
 | 52 | +#[async_trait]  | 
 | 53 | +impl TypedAction for SenderAction {  | 
 | 54 | +    type I = ();  | 
 | 55 | +    type O = String;  | 
 | 56 | + | 
 | 57 | +    async fn run(  | 
 | 58 | +        &self,  | 
 | 59 | +        _: TypedInChannels<Self::I>,  | 
 | 60 | +        out: TypedOutChannels<Self::O>,  | 
 | 61 | +        _: Arc<EnvVar>,  | 
 | 62 | +    ) -> Output {  | 
 | 63 | +        // Send the message to all receivers  | 
 | 64 | +        out.broadcast(self.message.clone()).await;  | 
 | 65 | +        Output::Out(None)  | 
 | 66 | +    }  | 
 | 67 | +}  | 
 | 68 | + | 
 | 69 | +/// An action that sends a message to its output channel after a delay  | 
 | 70 | +#[derive(Default)]  | 
 | 71 | +pub struct SlowSenderAction {  | 
 | 72 | +    message: String,  | 
 | 73 | +}  | 
 | 74 | + | 
 | 75 | +impl SlowSenderAction {  | 
 | 76 | +    pub fn new(message: String) -> Self {  | 
 | 77 | +        Self { message }  | 
 | 78 | +    }  | 
 | 79 | +}  | 
 | 80 | + | 
 | 81 | +#[async_trait]  | 
 | 82 | +impl TypedAction for SlowSenderAction {  | 
 | 83 | +    type I = ();  | 
 | 84 | +    type O = String;  | 
 | 85 | + | 
 | 86 | +    async fn run(  | 
 | 87 | +        &self,  | 
 | 88 | +        _: TypedInChannels<Self::I>,  | 
 | 89 | +        out: TypedOutChannels<Self::O>,  | 
 | 90 | +        _: Arc<EnvVar>,  | 
 | 91 | +    ) -> Output {  | 
 | 92 | +        // Wait for 500ms before sending  | 
 | 93 | +        sleep(Duration::from_millis(500)).await;  | 
 | 94 | +        // Send the message to all receivers  | 
 | 95 | +        out.broadcast(self.message.clone()).await;  | 
 | 96 | +        Output::Out(None)  | 
 | 97 | +    }  | 
 | 98 | +}  | 
 | 99 | + | 
 | 100 | +/// An action that receives messages from any available channel  | 
 | 101 | +#[derive(Default)]  | 
 | 102 | +pub struct ReceiverAction;  | 
 | 103 | + | 
 | 104 | +#[async_trait]  | 
 | 105 | +impl TypedAction for ReceiverAction {  | 
 | 106 | +    type I = String;  | 
 | 107 | +    type O = ();  | 
 | 108 | + | 
 | 109 | +    async fn run(  | 
 | 110 | +        &self,  | 
 | 111 | +        mut input: TypedInChannels<Self::I>,  | 
 | 112 | +        _: TypedOutChannels<Self::O>,  | 
 | 113 | +        _: Arc<EnvVar>,  | 
 | 114 | +    ) -> Output {  | 
 | 115 | +        // Receive from any available channel  | 
 | 116 | +        match input.recv_any().await {  | 
 | 117 | +            Ok((sender_id, content)) => {  | 
 | 118 | +                let message = content.unwrap();  | 
 | 119 | +                println!("Received message '{}' from node {:?}", message, sender_id);  | 
 | 120 | +            }  | 
 | 121 | +            Err(e) => {  | 
 | 122 | +                eprintln!("Error receiving message: {:?}", e);  | 
 | 123 | +            }  | 
 | 124 | +        }  | 
 | 125 | + | 
 | 126 | +        match input.recv_any().await {  | 
 | 127 | +            Ok((sender_id, content)) => {  | 
 | 128 | +                let message = content.unwrap();  | 
 | 129 | +                println!("Received message '{}' from node {:?}", message, sender_id);  | 
 | 130 | +            }  | 
 | 131 | +            Err(e) => {  | 
 | 132 | +                eprintln!("Error receiving message: {:?}", e);  | 
 | 133 | +            }  | 
 | 134 | +        }  | 
 | 135 | + | 
 | 136 | +        Output::Out(None)  | 
 | 137 | +    }  | 
 | 138 | +}  | 
 | 139 | + | 
 | 140 | +fn main() {  | 
 | 141 | +    // Create a node table  | 
 | 142 | +    let mut node_table = NodeTable::new();  | 
 | 143 | + | 
 | 144 | +    // Create sender nodes  | 
 | 145 | +    let sender1 = DefaultNode::with_action(  | 
 | 146 | +        "Sender1".to_string(),  | 
 | 147 | +        SenderAction::new("Hello from Sender".to_string()),  | 
 | 148 | +        &mut node_table,  | 
 | 149 | +    );  | 
 | 150 | +    let sender2 = DefaultNode::with_action(  | 
 | 151 | +        "Sender2".to_string(),  | 
 | 152 | +        SlowSenderAction::new("Hello from SlowSender".to_string()),  | 
 | 153 | +        &mut node_table,  | 
 | 154 | +    );  | 
 | 155 | + | 
 | 156 | +    // Create receiver node  | 
 | 157 | +    let receiver = DefaultNode::with_action(  | 
 | 158 | +        "Receiver".to_string(),  | 
 | 159 | +        ReceiverAction::default(),  | 
 | 160 | +        &mut node_table,  | 
 | 161 | +    );  | 
 | 162 | + | 
 | 163 | +    // Get node IDs before adding nodes to the graph  | 
 | 164 | +    let sender1_id = sender1.id();  | 
 | 165 | +    let sender2_id = sender2.id();  | 
 | 166 | +    let receiver_id = receiver.id();  | 
 | 167 | + | 
 | 168 | +    // Create a graph  | 
 | 169 | +    let mut graph = Graph::new();  | 
 | 170 | + | 
 | 171 | +    // Add nodes to the graph  | 
 | 172 | +    graph.add_node(sender1);  | 
 | 173 | +    graph.add_node(sender2);  | 
 | 174 | +    graph.add_node(receiver);  | 
 | 175 | + | 
 | 176 | +    // Add edges: both senders connect to the receiver  | 
 | 177 | +    graph.add_edge(sender1_id, vec![receiver_id]);  | 
 | 178 | +    graph.add_edge(sender2_id, vec![receiver_id]);  | 
 | 179 | + | 
 | 180 | +    // Run the graph  | 
 | 181 | +    match graph.start() {  | 
 | 182 | +        Ok(_) => (),  | 
 | 183 | +        Err(e) => {  | 
 | 184 | +            eprintln!("Graph execution failed: {:?}", e);  | 
 | 185 | +        }  | 
 | 186 | +    }  | 
 | 187 | +}  | 
0 commit comments