Design 25: the store window, and what moving it into the server changes
The guarantee is the same and the mechanism is simpler — a nak with a delay, no parked list, nothing lost when the controller restarts. It costs one thing: a naked message comes back whatever happened meanwhile, so an older report is redelivered after a newer was applied. A report already carries the digest of the declaration it answers, so supersession becomes a check rather than memory — ordering settled by what a message says, not by when it arrived.
This commit is contained in:
@@ -128,6 +128,33 @@ call is a timeout the caller already handles.
|
||||
Streams and consumers are objects the controller creates at genesis and asserts on start; a module
|
||||
declares nothing about them. The controller is the only writer of stream definitions.
|
||||
|
||||
### The store window, and what moving it into the server changes
|
||||
|
||||
The guarantee ([ADR 0083](../../02-DECISIONS/0083-one-push-leaves-the-mesh-consistent.md)) is
|
||||
that a push the controller cannot record because its store is restarting is **held and retried** —
|
||||
never dropped, never falsely acknowledged. Here that is a `nak` with a delay: the server holds
|
||||
the message and redelivers it, so the controller keeps no list of parked messages and one that
|
||||
restarts mid-window loses nothing it was holding.
|
||||
|
||||
**That is a plain win, and it introduces one problem worth naming.** Holding a delivery in memory
|
||||
let the controller drop an older report when a newer one for the same node arrived, because
|
||||
acting on the older after the newer would undo the newer. A `nak`ed message belongs to the server
|
||||
and comes back whatever happened meanwhile — so the older report is redelivered *after* the newer
|
||||
was applied.
|
||||
|
||||
The answer was already in the message. A report carries the **digest of the declaration it is
|
||||
about**, which exists because an earlier attempt to order reports by time lost the race it
|
||||
invited: an apply that began under the previous declaration finishes after the next is sent, and
|
||||
its report reads as newer than the send. Clocks cannot answer *which*.
|
||||
|
||||
So supersession stops being something the controller remembers and becomes something it checks —
|
||||
a report whose digest is not the one outstanding for that node is acknowledged without being
|
||||
acted on. The same shape as a node refusing a superseded declaration by sequence
|
||||
([issue 107](../../04-ISSUES/107-a-declaration-carries-no-order/00-report.md)): **ordering settled
|
||||
by what a message says, not by when it arrived.** And staleness is checked before the store is
|
||||
waited on, so a redelivery that lost its race does not hold a slot in the window that a current
|
||||
message needs.
|
||||
|
||||
## 4. Accounts
|
||||
|
||||
[ADR 0043](../../02-DECISIONS/0043-a-module-broker-account-is-scoped-by-emits-and-consumes.md) says a
|
||||
|
||||
Reference in New Issue
Block a user