D1: the assigner, builder and indexer call every node's manifest-reads again at their consumer's bind (issue 1966, ADR 0668 §4)
Note 155: a manifest-reads-changed said before the assigner's consumer existed was never heard, and ace's bootstrapped statement stood. Each part registers the engine-reads keeper's AtBind on its hub and calls the verb as a kept call (CallKeptOn). The asks-at-bind half (Q7) is not in this commit. Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
@@ -263,7 +263,7 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro
|
||||
watch.put = gate.Toolchain
|
||||
// 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.CallOn, gate, logger.Printf)
|
||||
reads := newEngineReads(calls.CallKeptOn, gate, logger.Printf)
|
||||
// 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)
|
||||
@@ -351,6 +351,7 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro
|
||||
if err := hub.Handle("mesh.seat.*.event.>", events); err != nil {
|
||||
return err
|
||||
}
|
||||
hub.OnBound(reads.atBind) // what a node's engine said before the consumer was bound (ADR 0668 §4)
|
||||
if stopped != nil {
|
||||
return stopped
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"slices"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/nats.go/jetstream"
|
||||
|
||||
@@ -35,7 +36,7 @@ type engineReads struct {
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// newEngineReads asks through call (process.Conn.CallOn) and keeps each answer in the state once it is bound.
|
||||
// newEngineReads asks through call (process.Conn.CallKeptOn, a kept call; ADR 0668) and keeps each answer in the state once it is bound.
|
||||
func newEngineReads(call enginereads.Caller, gate *buildrun.ToolchainGate, logf func(string, ...any)) *engineReads {
|
||||
r := &engineReads{gate: gate, keeper: &enginereads.Keeper{Call: call, Logf: logf}}
|
||||
r.keeper.Changed = r.stepWindow
|
||||
@@ -107,6 +108,16 @@ func (r *engineReads) placed() {
|
||||
r.stepWindow()
|
||||
}
|
||||
|
||||
// atBind asks every counted node again when the builder's consumer is bound (the hub's OnBound): a manifest-reads-changed
|
||||
// said before the consumer existed is not delivered to it, so the statement it would have ended is ended here (novox/hq
|
||||
// ADR 0668 §4; issue 1966 note 155).
|
||||
func (r *engineReads) atBind(created time.Time) {
|
||||
r.mu.Lock()
|
||||
nodes := slices.Clone(r.counted)
|
||||
r.mu.Unlock()
|
||||
r.keeper.AtBind(func() []string { return nodes })(created)
|
||||
}
|
||||
|
||||
// heard takes an event of the builder's consumer on EVENTS: manifest-reads-changed asks its node again, and answers true.
|
||||
func (r *engineReads) heard(m jetstream.Msg, logf func(string, ...any)) bool {
|
||||
node, ours, err := enginereads.NodeOf(m.Subject(), m.Data())
|
||||
|
||||
@@ -414,6 +414,18 @@ func aFailedTrunkBuildIsAFinding(t *testing.T) {
|
||||
said: func(b versions.OldFormClosedBody) { closings = append(closings, b) },
|
||||
log: func(e builds.BuildLogEntry) { logged = append(logged, e) }}
|
||||
reads := &engineReads{keeper: &enginereads.Keeper{}, window: window, counted: []string{"a", "b"}}
|
||||
// Issue 1966 note 155, ADR 0668 §4: at the consumer's bind every counted node is called once again.
|
||||
var boundCalls []string
|
||||
reads.keeper.Sync = true
|
||||
reads.keeper.Call = func(node, _ string, _ any) (json.RawMessage, error) {
|
||||
boundCalls = append(boundCalls, node)
|
||||
return nil, errors.New("not served")
|
||||
}
|
||||
reads.atBind(now)
|
||||
if !slices.Equal(boundCalls, []string{"a", "b"}) {
|
||||
t.Fatalf("at the bind called %v, want every counted node once", boundCalls)
|
||||
}
|
||||
reads.keeper = &enginereads.Keeper{}
|
||||
newest := []string{forms.FormNeed("oci")}
|
||||
counted := map[string][]string{"a": newest, "b": nil}
|
||||
window.step(context.Background(), []string{"a", "b"}, counted)
|
||||
|
||||
Reference in New Issue
Block a user