Skip to content

03 — Dependencies & parallelism

The dependencies list on each Task defines the DAG edges. Tasks with no dependency between them run in parallel.

fetch → (transform_a, transform_b in parallel) → combine.

#[workflow(name = "diamond", description = "Fan out then fan in")]
pub mod diamond {
use super::*;
#[task]
pub async fn fetch(ctx: &mut Context<serde_json::Value>) -> Result<(), TaskError> { Ok(()) }
#[task(dependencies = ["fetch"])]
pub async fn transform_a(ctx: &mut Context<serde_json::Value>) -> Result<(), TaskError> { Ok(()) }
#[task(dependencies = ["fetch"])]
pub async fn transform_b(ctx: &mut Context<serde_json::Value>) -> Result<(), TaskError> { Ok(()) }
#[task(dependencies = ["transform_a", "transform_b"])]
pub async fn combine(ctx: &mut Context<serde_json::Value>) -> Result<(), TaskError> { Ok(()) }
}

transform_a and transform_b both depend only on fetch, so the engine runs them concurrently; combine waits for both. The DAG is validated when the workflow is built — cycles and missing tasks are rejected.