state buckets
Buckets are declared at the top of the config file and referred to by the pipelines that use them — deliberately the shape connections already have, and global for the same reason: one pipeline remembers the current recipe per machine, and six unrelated ones stamp it onto their output.
the rule that isn't enforced
Two pipelines sharing a bucket are two run loops with no ordering between them. Ordering-sensitive correlation has to live in one pipeline; sharing is for state that doesn't change on the timescale of a message. Nothing prevents this — it is a property of what you are computing, not of the config.
Every bucket is bounded and there is no unbounded spelling, expiry is applied when a bucket is touched rather than by a sweeper, and contents survive a config reload unless that bucket's own declaration changed. The narrative, and what remember / recall do with all this, is in state.
state bucket
state.<name>
One named bucket, and the bounds on it.
Both bounds have defaults and neither can be turned off. A keyed store with no limit is not a feature, it is a memory leak that takes a week to show up — so the question is only ever what the limits are.
| field | type | description | |
|---|---|---|---|
idle_timeout_secs | integer | optional | forget a key this many seconds after it was last written. Without it a machine that is decommissioned holds its slot until the bucket fills. Measured from the last write rather than the last read: a value nothing has written for an hour is stale whether or not something is still asking for it. |
max_keys | integer | optional | most keys to hold at once. Past this the least recently written key is dropped to make room, so a bucket is a cache of the active keys rather than a record of every key ever seen. Defaults to 10000. |
pipeline state
pipelines[].state
A pipeline's binding to a bucket: which one, and what its messages are keyed by.
The key lives here rather than on the bucket because it is a property of this stream — the same machine id arrives as _meta.machine_id from a nats subscription and as machine_id after a reducer has flattened it, and both are correct. The cost is that two pipelines sharing a bucket can key it differently with nothing to catch them, which is the sharp edge of sharing and is documented rather than prevented.
| field | type | description | |
|---|---|---|---|
bucket | string | required | name of the bucket this pipeline reads and writes — one of the ones declared under state at the top of the config. A pipeline naming a bucket that isn't declared fails to build. |
key | string | optional | the field whose value identifies the thing being remembered, e.g. _meta.machine_id. A dotted path like anywhere else. Leave it out for one bucket-wide value — which is the right answer for something there is only ever one of, and the wrong one for anything per-device. |