Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Layer Graphs — Dependency Planning

LayerGraph is a planner for named layer nodes. It does not build layers itself; it computes a topological build order from requires and provides service names.

Declaring a Layer Graph

use effectful::{LayerGraph, LayerNode};

let graph = LayerGraph::new([
    LayerNode::new("config", std::iter::empty::<&str>(), ["config"]),
    LayerNode::new("db", ["config"], ["db"]),
    LayerNode::new("cache", ["config"], ["cache"]),
    LayerNode::new("service", ["db", "cache"], ["service"]),
]);

Each node has:

  • id: stable unique node id
  • requires: service names it needs
  • provides: service names it supplies

Planning

let plan = graph.plan_topological()?;
assert_eq!(plan.build_order, vec!["config", "db", "cache", "service"]);

Sibling order is deterministic but should not be used as a semantic dependency. If one layer must precede another, express that with requires / provides.

Planner Errors

plan_topological can fail with:

ErrorMeaning
DuplicateNodeIdTwo nodes share an id
ConflictingProviderMore than one node provides the same service name
MissingProviderA requirement has no provider
CycleDetectedDependencies contain a cycle
let bad_graph = LayerGraph::new([
    LayerNode::new("a", ["b"], ["a"]),
    LayerNode::new("b", ["a"], ["b"]),
]);

let err = bad_graph.plan_topological();
assert!(matches!(err, Err(LayerPlannerError::CycleDetected { .. })));

Use error.to_diagnostic() for user-facing messages and suggestions.

Planning from STM

LayerGraph::plan_topological_from_tref(&nodes_tref) reads a TRef<Vec<LayerNode>> snapshot transactionally and plans from that snapshot.

When to Use LayerGraph

Use LayerGraph when you need validation, diagnostics, or tool-visible dependency order. For a few layers in application code, direct layer composition is usually clearer.