This page is the guide — the shapes and when to use them. The complete field-level
contract lives in the accumulation reference.
accumulate: wait for several events
accumulate gathers arrivals for one entity and fires only when a completion condition is met.
The expected count is read from entity state through expected_from:
accumulated is the list of arrivals collected so far, readable in on_complete conditions.
Until completion, the handler records the arrival and stops. One thing to watch: dedup_by
defaults to the sender, which silently collapses several items from one sender into one; set
it to the distinguishing payload field. That default and the materialize_from projection are
covered in Accumulation and projection.
compute: aggregate into one value
compute runs a built-in aggregation and stores the result on the entity (store_as names an
entity field):
entity.composite, weighting quality/speed/cost
at 60% and innovation/scalability at 40%.
filter, reduce, count: process a list
These operate on a list (an entity field or a payload list) and store a result. Their conditions reference each element asitem:
fan_out: one event per item
fan_out emits one event per item in a list. Each emitted payload is built with fields, where
item is the current element. fan_out.count is how many events were dispatched:
fan_out.count is only available to data_accumulation in the same handler.
The example above records a count for reporting — do not use a count as a completion
barrier. Don’t hand-roll a counter with
accumulate and
expected_count comparisons — that pattern has no dedup and no timeout, and it deadlocks
if the last result arrives before the count is written. The platform has a purpose-built
barrier for this — a fan-in pin feeding a join: row, which handles dedup, membership, and
timeout for you. See examples/routing/fan-in/barrier for the canonical
shape. accumulate remains right for aggregations that are not completion barriers.query: read across entities
query pre-fetches data from other entities, for reports or cross-entity decisions:
count: true here asks the query to return counts — not the count step above.
A query can also filter, select specific fields, and store_as a named result; see
Handler fields for the full option list.
