The keeper's health reads the consumers it looks for (issue 1966, recovery) #636

Merged
mesh-tools merged 1 commits from fix/keeper-health-consumers into main 2026-11-08 22:55:46 +00:00
2 changed files with 18 additions and 1 deletions
+6 -1
View File
@@ -172,13 +172,18 @@ var ReadingVerbs = []string{"list", "show", "check", "orphans"}
// and kept in full on the bus module's own stream broker-events (BROKER_EVENTS), which `history` reads (keep.go).
var Events = []string{"created", "refused", "drifted", "drift-cleared", "full", "full-cleared", "orphaned", "recreated", "dropped"}
// heldJsz is the monitoring read the broker's verbs and the keeper's health share: with the consumers, since the
// keeper's health reads what waits on its own consumer from it (keeperPending); without them it read -1 and the keeper
// was never healthy (2026-11-08, issue 1966).
const heldJsz = "/jsz?accounts=1&streams=1&consumers=1&config=1"
// allTools is every tool and seat verb this bundle serves.
func allTools() []stdio.Tool {
monitor := LiveMonitor()
jsz := func() ([]byte, error) {
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
return monitor(ctx, "/jsz?accounts=1&streams=1&config=1")
return monitor(ctx, heldJsz)
}
out := append(tools(monitor, ReadUsers, UsersWritten), removalTools(LiveBus(), SaidByTheRuntime, HeldInState)...)
out = append(out, expiryTools(LiveBus(), SaidByTheRuntime, RecordedBySeat)...)
+12
View File
@@ -277,3 +277,15 @@ func TestTheRemovalToolsRefuseBeforeTheyReachTheBus(t *testing.T) {
}
}
}
// The keeper's health reads what waits on its own consumer from the shared monitoring read: that read asks for the
// consumers, or the health answers "cannot be read" for ever (2026-11-08, issue 1966).
func TestTheHeldReadAsksForTheConsumers(t *testing.T) {
if !strings.Contains(heldJsz, "consumers=1") {
t.Fatalf("the monitoring read %q asks for no consumers, so keeperPending never finds the keeper's", heldJsz)
}
doc := []byte(`{"account_details":[{"stream_detail":[{"name":"EVENTS","consumer_detail":[{"name":"novox_nats_keeper","num_pending":2}]}]}]}`)
if got := keeperPending(doc); got != 2 {
t.Fatalf("keeperPending = %d on a read with the keeper's consumer, want 2", got)
}
}