macula_group_epoch (macula v13.4.0)
View SourceA sealed group's epochs (plans/DESIGN_E2E_SEALED_PUBSUB.md §4).
An epoch is a group key for a stretch of time: a 32-byte key drawn at random, independent of every other epoch's, so holding one says nothing about the next; an 8-byte id drawn at random, which names the epoch on every sealed event (seal_key_id) and is bound to the key only by the distributor's signed reply; and its times. Epochs are contiguous: the next one is issued where this one stops publishing. A publisher seals under an epoch until its publish_until; a subscriber accepts events under it until its accept_until, which is publish_until plus the longest a publication lives (60 minutes of ttl plus 5 of tolerance, as macula_frame verifies a publication), and with the same 5-minute clock tolerance. After that the key has no use and is erased.
The last third of an epoch is its ahead window: a pull in it is also handed the next epoch, and every holder re-pulls at a random instant in it, so a rotation is spread over that third rather than asked for in one instant.
Everything here is a pure function of the epochs and the time it is given.
Summary
Functions
Whether an event under Epoch is accepted at Now: until its accept_until, with the 5-minute clock tolerance a publication gets.
Epoch's ahead window, {From, To}: the last third of its publishing stretch, To excluded.
How long an epoch publishes by default: 15 minutes.
The epoch a publisher seals under at Now: the newest held epoch that has been issued and has not stopped publishing, or {error, no_current_epoch} when none has (so the publisher fails closed until a pull succeeds).
Whether Now falls in Epoch's ahead window.
The held epochs still of use at Now; the others are erased.
A fresh epoch issued at IssuedAt (milliseconds), publishing for RotateAfterMs.
The epoch after Epoch: issued where it stops publishing, with a fresh key and id.
The instant a holder re-pulls: Fraction (0.0 inclusive to 1.0 exclusive, drawn uniformly by the caller) of the way through Epoch's ahead window.
Types
Functions
Whether an event under Epoch is accepted at Now: until its accept_until, with the 5-minute clock tolerance a publication gets.
-spec ahead_window(epoch(), pos_integer()) -> {integer(), integer()}.
Epoch's ahead window, {From, To}: the last third of its publishing stretch, To excluded.
-spec default_rotate_after_ms() -> pos_integer().
How long an epoch publishes by default: 15 minutes.
The epoch a publisher seals under at Now: the newest held epoch that has been issued and has not stopped publishing, or {error, no_current_epoch} when none has (so the publisher fails closed until a pull succeeds).
-spec in_ahead_window(epoch(), pos_integer(), integer()) -> boolean().
Whether Now falls in Epoch's ahead window.
The held epochs still of use at Now; the others are erased.
-spec new(integer(), pos_integer()) -> epoch().
A fresh epoch issued at IssuedAt (milliseconds), publishing for RotateAfterMs.
-spec next(epoch(), pos_integer()) -> epoch().
The epoch after Epoch: issued where it stops publishing, with a fresh key and id.
-spec repull_at(epoch(), pos_integer(), float()) -> integer().
The instant a holder re-pulls: Fraction (0.0 inclusive to 1.0 exclusive, drawn uniformly by the caller) of the way through Epoch's ahead window.