Skip to main content
Cloacina Documentation
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

03 — Dependencies & parallelism

03 — Dependencies & parallelism

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

A diamond

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(()) }
}
with cloaca.WorkflowBuilder("diamond") as builder:
    builder.description("Fan out then fan in")

    @cloaca.task()
    def fetch(context): return context

    @cloaca.task(dependencies=["fetch"])
    def transform_a(context): return context

    @cloaca.task(dependencies=["fetch"])
    def transform_b(context): return context

    @cloaca.task(dependencies=["transform_a", "transform_b"])
    def combine(context): return context

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.

Next