From abf5eace779112eb2661d9cb306cb7a1cbe39dec Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 2 Nov 2026 12:25:56 +0100 Subject: [PATCH] Let the bus tools remove mesh-catalog's and the engines' leftover consumers on EVENTS novox_mesh-catalog follows the ended controller's built-before and each _mesh-host restic's backed-up; no part composes either and nothing reads them (novox_mesh-catalog 10036 behind, each mesh-host 331 never delivered), so the removal after the delivery takes them with the controller's (issue 1126). Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL --- go/buscompose/buscompose_test.go | 4 ++++ go/buscompose/health_grants.go | 22 ++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/go/buscompose/buscompose_test.go b/go/buscompose/buscompose_test.go index 8f84706..d31d1e6 100644 --- a/go/buscompose/buscompose_test.go +++ b/go/buscompose/buscompose_test.go @@ -677,6 +677,10 @@ func healthChecks(t *testing.T) { "$JS.API.STREAM.DELETE.CONTROL", "$JS.API.STREAM.DELETE.OBJ_declaration-files-a", "$JS.API.CONSUMER.DELETE.EVENTS.controller", "$JS.API.CONSUMER.DELETE.EVENTS.controller-merges", "$JS.API.CONSUMER.DELETE.EVENTS.novox_mesh-delivery", "$JS.API.CONSUMER.DELETE.CONTROL.controller", + // And the consumers no part composes that the controller made before it ended: mesh-catalog's of the + // controller's built-before, and each node's engine's of restic's backed-up (issue 1126). + "$JS.API.CONSUMER.INFO.EVENTS.novox_mesh-catalog", "$JS.API.CONSUMER.DELETE.EVENTS.novox_mesh-catalog", + "$JS.API.CONSUMER.INFO.EVENTS.a_mesh-host", "$JS.API.CONSUMER.DELETE.EVENTS.a_mesh-host", "$JS.API.CONSUMER.INFO.CONTROL.controller"}, } mayNot := map[string][]string{ diff --git a/go/buscompose/health_grants.go b/go/buscompose/health_grants.go index 0b811c4..29036e9 100644 --- a/go/buscompose/health_grants.go +++ b/go/buscompose/health_grants.go @@ -24,13 +24,27 @@ import ( // HealersWould is what mesh-healers would have done while a controller was placed: read by nobody (ADR 0564 clause 8). var HealersWould = health.HealersModule + "." + health.WouldState -// ControllerLeftoverConsumers are the ended controller's durable consumers left on the bus, and one leftover of the -// module mesh-delivery placed nowhere (issue 1126, milestone section 3), each `.`. +// ControllerLeftoverConsumers are the ended controller's durable consumers left on the bus, one leftover of the module +// mesh-delivery placed nowhere (issue 1126, milestone section 3), and mesh-catalog's of the controller's built-before, +// which its manifest no longer consumes and no part composes; each `.`. var ControllerLeftoverConsumers = []string{ - "EVENTS." + ControllerName, "EVENTS." + MergesConsumerName, "EVENTS.novox_mesh-delivery", + "EVENTS." + ControllerName, "EVENTS." + MergesConsumerName, "EVENTS.novox_mesh-delivery", "EVENTS.novox_mesh-catalog", "CONTROL." + ControllerName, DeadLetterNoticesStream + "." + ControllerName, } +// ControllerLeftoverConsumersOn are ControllerLeftoverConsumers and, for each node given, the consumer the controller +// made for the node's engine (`EVENTS._mesh-host`, of restic's backed-up): the engine hears that event without a +// durable consumer, and the grants part composes none for it, so nothing reads it (issue 1126). +func ControllerLeftoverConsumersOn(nodes []string) []string { + out := slices.Clone(ControllerLeftoverConsumers) + for _, n := range nodes { + if safeSubject.MatchString(n) { + out = append(out, "EVENTS."+n+"_"+EngineModule) + } + } + return out +} + // ControllerLeftoverBuckets are the ended controller's buckets, each by its local name (`KV_mesh-controller_`). var ControllerLeftoverBuckets = []string{"asked", "assignments", "builds", "calls", "checks-running", "composed", "condition-history", "conditions", "declared-config", "declared-packages", "delivery-merges", "grants", "hand-acts", @@ -64,7 +78,7 @@ func BusRemovalGrants(removes, nodes []string) ([]string, error) { case catalogue.RemovesEngineActs: out = append(out, "$JS.API.STREAM.INFO.KV_"+EngineActsBucket, "$KV."+EngineActsBucket+".>") case catalogue.RemovesControllerLeftovers: - for _, c := range ControllerLeftoverConsumers { + for _, c := range ControllerLeftoverConsumersOn(nodes) { out = append(out, "$JS.API.CONSUMER.INFO."+c, "$JS.API.CONSUMER.DELETE."+c) } for _, s := range ControllerLeftoverStreams(nodes) {