# `Controls.Accumulator`
[🔗](https://github.com/harmont-dev/hyper/blob/main/lib/controls/accumulator.ex#L1)

Accrues consumption from a monotonically increasing cumulative counter,
tolerating counter resets (the counter's source was destroyed and recreated,
restarting from zero — e.g. a VM's cgroup across a restart).

  * `observe/2` folds in a cumulative reading: the first reading is a
    baseline; a reading `>=` the previous adds the delta; a reading *below*
    the previous is a reset, and the whole new reading is consumption
    accrued since recreation.
  * `total/1` reads the accrued consumption; `flush/1` zeroes it (call after
    the total has been durably recorded) while keeping the baseline.

Works on any `Unit.Quantity`. Laws under test: a monotone sequence accrues
exactly `last - first`; the total is never negative; observing the same
reading twice adds nothing; interleaved flushes conserve the grand total.

# `t`

```elixir
@opaque t()
```

# `flush`

```elixir
@spec flush(t()) :: t()
```

Zero the accrued consumption, keeping the baseline.

# `new`

```elixir
@spec new(Unit.Quantity.t()) :: t()
```

A fresh accumulator. `zero` is the zero quantity of the counter's dimension.

# `observe`

```elixir
@spec observe(t(), Unit.Quantity.t()) :: t()
```

Fold in the latest cumulative reading.

# `total`

```elixir
@spec total(t()) :: Unit.Quantity.t()
```

Consumption accrued since the last `flush/1`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
