mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-27 14:07:31 +00:00
88d44099aa
Each tenant monitor owns its own IncidentStore, but incident and incident-event IDs came from package-level int64 counters bumped with ++ under nothing but the calling store's mutex. Two tenants recording alerts at once raced on them: go test -race failed TestLeavingMockModeClearsEveryRunningTenantMonitor on PR 2698 at incidents.go:1753. The remediation record counter had the same shape, and remediation logs are created per org. All six internal/ai/memory ID generators now mint through one atomic helper. The numeric suffix also stops wrapping at 1000: even with atomic counters, one generator minting more than a thousand IDs in a wall-clock second repeated an ID, and incident notes find their incident by ID. The prefix and timestamp layout is unchanged, and intToString lost its last callers. ids_test.go mints 2,400 IDs from every generator on 16 goroutines and records alerts into two tenant stores concurrently. Against the old files it reports DATA RACE at incidents.go:1753/1760 and remediation.go:355, and every generator mints duplicate or wrapped IDs.
17 lines
571 B
Go
17 lines
571 B
Go
package memory
|
|
|
|
import (
|
|
"strconv"
|
|
"sync/atomic"
|
|
"time"
|
|
)
|
|
|
|
// nextSequencedID mints prefix + local wall-clock second + "-" + the next value
|
|
// of seq. Each sequence is package-level and shared by every store in the
|
|
// process, including one store per tenant monitor, so it must stay atomic.
|
|
// The suffix never wraps, so one sequence never repeats an ID within a process
|
|
// however many IDs share a second.
|
|
func nextSequencedID(prefix string, seq *atomic.Int64) string {
|
|
return prefix + time.Now().Format("20060102150405") + "-" + strconv.FormatInt(seq.Add(1), 10)
|
|
}
|