A gate judges its own send and the build it sent, and never puts the controller back behind its store (hq issue 352)
On 2026-10-09 a release's gate on the control node read the machine's
report against a newer send another plan had just made there, failed
three builds the machine had reported healthy, and put them back on
every machine to a controller older than the store's schema; that
controller then passed the newer plan's gate from its own health.
- A gate keeps what its send carried (digest, sequence) and reads the
report against it; a report on the last send is on it too.
- A gate judges only the build the machine was last sent: another build
there supersedes the judging — no verdict, nothing put back.
- A controller is told its build (MESH_CONTROLLER_VERSION, ${version}
in a process's env) and records how far it reads the store's schema;
a put-back to a build that reaches less, or never said, is refused
and the current build kept, said as urgent.
- A release's open gate holds other sends of its modules there, and a
plan's own first send waits on it.
This commit is contained in:
@@ -76,6 +76,21 @@ func serve(ctx context.Context) (err error) {
|
||||
}
|
||||
defer open.Close()
|
||||
inv := open.inventory
|
||||
// **What this build reads of the store's schema, on record** (novox/hq issue 352): the highest migration
|
||||
// it carries, by its version, so a gate that would put this build back later knows it reads the store
|
||||
// as it is then. A build that does not know its version records nothing, and is never put back.
|
||||
if build := runningBuild(); build != "" {
|
||||
if reach, err := schemaReach(); err != nil {
|
||||
fmt.Printf("what this build reads of the store's schema is not recorded: %v\n", err)
|
||||
} else if err := inv.RecordSchemaReach(ctx, build, reach); err != nil {
|
||||
fmt.Printf("what this build (%s) reads of the store's schema is not recorded: %v\n", build, err)
|
||||
} else {
|
||||
fmt.Printf("this build (%s) reads the store's schema up to migration %04d; recorded\n", build, reach)
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("this process was not told which build it is (%s), so what it reads of the store's schema is not "+
|
||||
"recorded, and a gate will never put it back\n", RunningBuildVar)
|
||||
}
|
||||
|
||||
ident, err := openIdentity(ctx)
|
||||
if err != nil {
|
||||
@@ -1598,3 +1613,18 @@ func reportUnheldPushed(w io.Writer, named bool, asked []string, unheld map[stri
|
||||
fmt.Fprintf(w, "%s: %d unmet seat dependenc(ies) — see `status`\n", node, len(lines))
|
||||
}
|
||||
}
|
||||
|
||||
// schemaReach is the highest migration this build carries for the inventory's store (novox/hq issue 352).
|
||||
func schemaReach() (int, error) {
|
||||
migrations, err := inventory.Migrations()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
reach := 0
|
||||
for _, m := range migrations {
|
||||
if m.Number > reach {
|
||||
reach = m.Number
|
||||
}
|
||||
}
|
||||
return reach, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user