ReactiveDag.Node.RecomputeBy (reactive_dag v0.17.0-rc)

Copy Markdown View Source

THE declaration the engine cares about: what unit does a change invalidate? Everything else a combinator declares — group_by, into, key derivation — is mapping data into shape once you already know what to recompute.

recompute_by :category, from: :expense_cat

Read: "recompute by category, from the input's expense_cat" — a change to a row's expense_cat invalidates my category unit, so redo it whole. That one fact supplies the input edge, the grouping, the claim resolution and the read scope, so it replaces the key_rule vocabulary entirely.

Four answers to the one question:

  • recompute_by :cell — the whole cell; any change re-does everything (a fold whose every output depends on every input).
  • recompute_by :cat, from: :child_field — per unit, resolved by READING the changed rows and evaluating the field. A key the lookup can't find (a deleted row) degrades to whole-cell: vanish must reprice everything it might have left.
  • recompute_by :month, from_key: true — per unit, resolved PURELY from the changed key's leading |-segments. No query and deletion-safe, at the price of the key-grammar contract.
  • (omitted) — key-for-key: a changed input key maps to the same output key.

NOTE this is the RECOMPUTE unit, not the output's grain. They coincide for a plain rollup, and diverge the moment one unit emits many rows: percentiles per day recompute_by :day (touch one reading, redo that day) while the rows are keyed day+percentile via expand:.

The unit is consumed at COMPILE time — it lowers to the combinator's over:

  • group_by: pair and is never traversed at recompute. One declaration per node, so a combinator reads exactly one input: one unit, one claim translation.