Dynamic Router
Example of using RouterNode for dynamic branching.
This example demonstrates how to use RouterNode to dynamically select which path to execute.
use std::sync::Arc;
use async_trait::async_trait;
use dagrs::{
Action, DefaultNode, EnvVar, Graph, InChannels, Node, NodeTable, OutChannels, Output,
Router, RouterNode,
};
struct MyRouter {
select_left: bool,
left_node_id: usize,
right_node_id: usize,
}
#[async_trait]
impl Router for MyRouter {
async fn route(
&self,
_: &mut InChannels,
_: &OutChannels,
_: Arc<EnvVar>,
) -> Vec<usize> {
if self.select_left {
vec![self.left_node_id]
} else {
vec![self.right_node_id]
}
}
}
struct PrintAction(String);
#[async_trait]
impl Action for PrintAction {
async fn run(&self, _: &mut InChannels, _: &mut OutChannels, _: Arc<EnvVar>) -> Output {
println!("{}", self.0);
Output::empty()
}
}
#[tokio::main]
async fn main() {
let mut table = NodeTable::new();
let mut graph = Graph::new();
// Left path
let left = DefaultNode::with_action("Left".to_string(), PrintAction("Left Path".into()), &mut table);
let id_left = left.id();
// Right path
let right = DefaultNode::with_action("Right".to_string(), PrintAction("Right Path".into()), &mut table);
let id_right = right.id();
// Router
let router = RouterNode::new(
"Router".to_string(),
MyRouter {
select_left: true, // Select left path
left_node_id: id_left.as_usize(),
right_node_id: id_right.as_usize(),
},
&mut table,
);
let id_router = router.id();
graph.add_node(left);
graph.add_node(right);
graph.add_node(router);
// Connect Router -> Left, Router -> Right
graph.add_edge(id_router, vec![id_left, id_right]);
println!("Starting graph execution...");
graph.start().unwrap();
// Output should contain "Left Path" but NOT "Right Path"
}