A declaration carries its order, and a host refuses an older one
novox/hq 04-ISSUES/107. A declaration's only identity was the digest of its bytes: a host could say "not the last" and could not say "older". On the link, nothing refused an older one at all, and the drain picked the last to arrive — wrong exactly when it mattered, a backlog drained out of order or a broker that split a burst. A declaration may now carry a sequence, one higher per send. A host refuses one lower than what it kept, whole, and says why. The drain keeps the highest sequence in a batch rather than the last to arrive. Only when both sides claim an order. Absent reads as zero — "no ordering claimed", not "first" — so a controller that sends none is still understood and a host that kept one before it understood them compares nothing. That is what lets hosts go first and the controller follow, which is the order 087 says a new field needs.
This commit is contained in:
@@ -1137,6 +1137,19 @@ type Declaration struct {
|
||||
// converged node — which is every node the mesh raised before adoption existed, and so the
|
||||
// only form an older controller ever sends (novox/hq ADR 0100).
|
||||
Adoption *Adoption
|
||||
|
||||
// Sequence orders this declaration against every other the mesh has sent this node: each
|
||||
// send is one higher than the last, assigned under the control plane's hold on the node
|
||||
// (novox/hq 04-ISSUES/107). Zero is a declaration that carries no order — every one an older
|
||||
// controller sent, and the bundle genesis applies — and a host makes no ordering claim about
|
||||
// one of those.
|
||||
//
|
||||
// **The one property a declaration needs that its signature does not give it.** A signature
|
||||
// says the mesh sent this; it cannot say the mesh sent it AFTER the one the host is holding.
|
||||
// Before this, "older" was inferred from arrival within a batch and a 750ms window, and a
|
||||
// backlog longer than the batch, or a slow broker, applied a declaration the mesh had already
|
||||
// superseded.
|
||||
Sequence int64
|
||||
}
|
||||
|
||||
// Adoption is a node's mode, as the controller records it: the node is adopted, and these are
|
||||
@@ -1274,6 +1287,9 @@ type envelope struct {
|
||||
// a bug quietly strip a machine.
|
||||
OwnsNothing bool `json:"owns_nothing,omitempty"`
|
||||
Resources []json.RawMessage `json:"resources"`
|
||||
// Sequence is optional on the wire, so a controller that does not send one is still
|
||||
// understood: absent reads as zero, which is "no ordering claimed" rather than "first".
|
||||
Sequence int64 `json:"sequence,omitempty"`
|
||||
}
|
||||
|
||||
func parse(raw []byte, allowActions bool) (*Declaration, error) {
|
||||
@@ -1290,7 +1306,7 @@ func parse(raw []byte, allowActions bool) (*Declaration, error) {
|
||||
env.Version, Version)}}
|
||||
}
|
||||
|
||||
d := &Declaration{Version: env.Version, For: env.For, Adoption: env.Adoption}
|
||||
d := &Declaration{Version: env.Version, For: env.For, Adoption: env.Adoption, Sequence: env.Sequence}
|
||||
var problems []string
|
||||
|
||||
if len(env.Resources) == 0 && !env.OwnsNothing {
|
||||
|
||||
Reference in New Issue
Block a user