use durare::{
DurableContext, DurableEngine, InMemoryProvider, ListFilter, Result, WorkflowOptions,
};
use std::sync::Arc;
use std::time::Duration;
#[durare::step]
async fn sum_step(ctx: &DurableContext, nums: Vec<i64>) -> Result<i64> {
tokio::time::sleep(Duration::from_millis(60)).await; Ok(nums.iter().sum())
}
#[durare::workflow]
async fn sum_chunk(ctx: DurableContext, nums: Vec<i64>) -> Result<i64> {
sum_step(&ctx, nums).await
}
#[durare::workflow]
async fn map_reduce(ctx: DurableContext, data: Vec<i64>) -> Result<i64> {
let mut children = Vec::new();
for chunk in data.chunks(3) {
let child = ctx
.start_workflow::<_, i64>("sum_chunk", chunk.to_vec(), WorkflowOptions::default())
.await?;
children.push(child);
}
let mut total = 0;
for child in children {
total += child.result().await?;
}
Ok(total)
}
#[tokio::main]
async fn main() -> Result<()> {
let engine = DurableEngine::new(Arc::new(InMemoryProvider::new())).await?;
let data: Vec<i64> = (1..=10).collect();
println!("[start] map_reduce over {data:?}");
let total: i64 = engine
.start_with(MapReduce, data, WorkflowOptions::with_id("mapreduce-1"))
.await?
.await?;
println!("[done] total = {total}\n");
assert_eq!(total, 55);
let mut children = engine
.list_workflows(&ListFilter {
workflow_id_prefix: vec!["mapreduce-1-".to_string()],
..Default::default()
})
.await?;
children.sort_by(|a, b| a.id.cmp(&b.id));
println!("[children] {} durable sub-workflows:", children.len());
for c in &children {
println!(
" {} -> {:?} (parent = {})",
c.id,
c.output.as_ref().unwrap(),
c.parent_workflow_id.as_deref().unwrap_or("-")
);
}
Ok(())
}