Problem
buildAlerts() in internal/source/collector.go:144 acquires c.mu first, then calls c.store.Snapshot() which acquires ss.mu.RLock — lock order: c.mu → ss.mu.
Collector.Snapshot() does the reverse sequentially (not nested): ss.mu.RLock then c.mu.
Currently safe because Snapshot() releases ss.mu before acquiring c.mu. But if someone refactors Snapshot() to hold ss.mu longer (e.g., to fix issue #1), the ordering becomes ss.mu → c.mu, which deadlocks against buildAlerts's c.mu → ss.mu.
Impact
Latent — only triggers if the code is refactored a specific way. No current deadlock.
Suggested Fix
Document the lock ordering convention (ss.mu before c.mu), or refactor buildAlerts to snapshot first, release store lock, then acquire c.mu to write alerts.
Files
internal/source/collector.go:144-182
Problem
buildAlerts()ininternal/source/collector.go:144acquiresc.mufirst, then callsc.store.Snapshot()which acquiresss.mu.RLock— lock order:c.mu → ss.mu.Collector.Snapshot()does the reverse sequentially (not nested):ss.mu.RLockthenc.mu.Currently safe because
Snapshot()releasesss.mubefore acquiringc.mu. But if someone refactorsSnapshot()to holdss.mulonger (e.g., to fix issue #1), the ordering becomesss.mu → c.mu, which deadlocks againstbuildAlerts'sc.mu → ss.mu.Impact
Latent — only triggers if the code is refactored a specific way. No current deadlock.
Suggested Fix
Document the lock ordering convention (
ss.mubeforec.mu), or refactorbuildAlertsto snapshot first, release store lock, then acquirec.muto write alerts.Files
internal/source/collector.go:144-182