Navigation

Build Simulator

This example models a small build planner. Nodes depend on other nodes, builders consume dependency outputs, and handlers provide cache, configuration, logging, and failure behavior.

The graph generators produce the scalable workloads used by the benchmark suite.

Graph nodes

Nodes are plain Nix records. A builder receives the evaluated dependency results and configuration, then returns either a value or an error marker.

nix
leaf = name: value: {
  inherit name;
  deps = [ ];
  builder = { deps, config }: value;
};

sumBuilder = { deps, config }:
  builtins.foldl' (acc: v: acc + v) (config.base or 0)
    (builtins.attrValues deps);

Effectful evaluation

The evaluator requests cache reads, cache writes, configuration, logging, and failure through effects. Swapping the handler changes observability without changing graph traversal.

nix
eval = graph:
  handle { handlers = handlersWithLogging; state = mkState graph; }
    (buildNode graph.root);

evalQuiet = graph:
  handle { handlers = handlersQuiet; state = mkState graph; }
    (buildNode graph.root);

Benchmark generators

graphs.nix generates linear, wide, diamond, tree, mixed, and failing graphs. The benchmark suite imports them from examples/build-sim.

nix
buildSim.graphs.benchmarks.linear500
buildSim.graphs.benchmarks.diamond10
buildSim.graphs.benchmarks.mixed_large