The keeper's health reads the consumers it looks for: the shared monitoring read asks for them
mesh/delivery merged: source.main moved to novox/mesh-catalog@08fbc51af26f
mesh/check checking 1ef1b1356044 on 08fbc51af26f
mesh/delivery merged: source.main moved to novox/mesh-catalog@08fbc51af26f
mesh/check checking 1ef1b1356044 on 08fbc51af26f
nats_keeper_health found the keeper's consumer novox_nats_keeper in /jsz, but the read it shares with the broker verbs asked /jsz?accounts=1&streams=1&config=1, without consumers=1, so keeperPending always read -1 and the keeper was "unhealthy: what waits on its consumer cannot be read from the bus's monitoring" for ever (2026-11-08, issue 1966). Claude-Session: https://claude.ai/code/session_01NcbgfFfQ4Z9UE5jK32PmE5
This commit is contained in:
@@ -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)...)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user