You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Two P2 items from Codex's second pass on `d7e5c43a`:
- Codex P2 #1 (keyviz_fanout.go) — fail-closed semantic
for legacy peer winners. The previous code used a
`j < len(row.RaftGroupIDs)` guard that SKIPPED the
assignment when the incoming source had empty arrays
(legacy peer in mixed-version cluster). That left the
stale identity from a previous higher-versioned source
in `dst.RaftGroupIDs[idx]`, mislabeling an unknown-term
winning cell as a known term and breaking the per-cell
dedupe/summing in PR-3c. Fixed by EXPLICITLY RESETTING
to 0 (the documented "term not tracked" sentinel) when
the incoming wins but its metadata array is shorter
than j. Caller audit: only mergeKeyVizMatrices calls
mergeRowInto; no external consumer relies on the
stale-identity behaviour.
- Codex P2 #2 (main.go publishLeaderTerms) — race
between the publisher's read of rt.engine and
rt.Close()'s write. Even after round-1's local-snapshot
fix, the initial read remained unsynchronized with
Close()'s write. Fixed structurally by adding
engineMu sync.RWMutex to raftGroupRuntime, exposing
snapshotEngine() that takes the read lock, and updating
Close() to take the write lock around clearing the
field.
Caller audit (per loop instruction — semantic change to
field access pattern): grepped all `rt.engine` /
`r.engine` reads:
- main.go:858, 1104, 1108, 1115 — startup wiring,
single-threaded BEFORE any goroutine launches; safe
to read directly.
- main_admin.go:828, 831, 837 (newClusterInfoSource) —
HTTP/gRPC handler closure, runs concurrent with
rt.Close(). SAME race class as the publisher.
Migrated to snapshotEngine() for consistency.
- multiraft_runtime.go:Close() — now takes engineMu
write lock.
No other readers exist outside startup.
Test: TestMergeKeyVizMatricesLegacyPeerWinnerResetsIdentity
drives a mixed-version cluster scenario (modern source
reports 30 with (group=7, term=42); legacy source reports
50 with empty arrays). Legacy wins maxMerge with value=50;
asserts dst.RaftGroupIDs / LeaderTerms reset to 0 instead
of inheriting modern's identity.
go test -race ./keyviz/... ./internal/admin/... — pass.
golangci-lint run (full project) — 0 issues.
0 commit comments