D7a: the assigner, the indexer and the builder ask a node's manifest-reads once before the kept call, so a node that answers nothing reads as its fallback at once (issue 1966, ADR 0668 §3; review round 1, finding 1)

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
2026-11-10 04:11:07 +01:00
parent bd39747c22
commit cddaf14cd0
3 changed files with 3 additions and 0 deletions
@@ -317,6 +317,7 @@ func follow(ctx context.Context, js jetstream.JetStream, nc process.Subscriber,
reads := &enginereads.Keeper{Fallback: w.recordReads, Changed: wake, Logf: logger.Printf}
if bus != nil {
reads.Call = bus.CallKeptOn // a kept call, called again through a transport fault (ADR 0668 §1)
reads.Once = bus.CallOn // its fault keeps the fallback at once while the kept call asks on (ADR 0668 §3)
}
if kv := kvs[engineReadsBucket]; kv != nil {
reads.Put = func(node string, v []byte) error { _, err := kv.Put(ctx, node, v); return err }
@@ -270,6 +270,7 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro
// What each counted node's engine reads (ADR 0618 §2, ADR 0624 §1): asked through the node-engine seat's verb as the
// builder's own account, for every node the assignments names, and kept in the state engine-reads once it is bound.
reads := newEngineReads(calls.CallKeptOn, gate, logger.Printf)
reads.keeper.Once = calls.CallOn // its fault keeps the last statement at once while the kept call asks on (ADR 0668 §3)
// The old reference form's window over them (DLV-B9), kept in the state old-form once it is bound; builder_old_form
// reads it and drops a retired node by hand.
reads.ctx = context.WithoutCancel(ctx)
@@ -493,6 +493,7 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro
// §2): asked through the node-engine seat's verb as the indexer's own account, for every node the assignments names,
// kept in the state engine-reads once it is bound; each change weighs the holds again.
reads := newEngineReads(calls.CallKeptOn, gate, func() { ix.KickHolds(ctx) }, logger.Printf)
reads.keeper.Once = calls.CallOn // its fault keeps the last statement at once while the kept call asks on (ADR 0668 §3)
gate.OnPlaced = reads.placed
ix.Counted, ix.AskEngines = reads.counted, reads.ask
// The holds, new with ADR 0632 (issue 1790's kind), bound when they appear: until then a merge that would hold a