fix data race in Patroni discovery cache after parallel source resolution #1401
Replies: 2 comments 2 replies
-
|
How did you trace it? Can you reproduce it? |
Beta Was this translation helpful? Give feedback.
-
|
I traced the issue from the real resolver code first: To verify that this is a real concurrency issue and not just a theoretical concern, I wrote a minimal focused repro test that exercises the same shared global map access pattern under concurrency: func TestLastFoundClusterMembersCacheConcurrentAccess(t *testing.T) {
t.Cleanup(func() {
lastFoundClusterMembers = make(map[string][]PatroniClusterMember)
})
const goroutines = 32
const iterations = 2000
var wg sync.WaitGroup
for g := 0; g < goroutines; g++ {
g := g
wg.Add(1)
go func() {
defer wg.Done()
for i := 0; i < iterations; i++ {
sourceName := fmt.Sprintf("source-%d", (g+i)%8)
members := []PatroniClusterMember{{
Name: fmt.Sprintf("member-%d-%d", g, i),
Scope: fmt.Sprintf("scope-%d", g%4),
ConnURL: fmt.Sprintf("postgres://source-%d/%d", g, i),
Role: "primary",
}}
lastFoundClusterMembers[sourceName] = members
_ = lastFoundClusterMembers[sourceName]
}
}()
}
wg.Wait()
}Running it under Command used: GOCACHE=/tmp/gocache \
GOMODCACHE=/tmp/gomodcache \
GOTMPDIR=/tmp/gotmp \
go test -race ./internal/sources \
-run TestLastFoundClusterMembersCacheConcurrentAccess \
-count=100So the concurrency issue seems reproducible once the cache is accessed concurrently after the parallel source discovery change. Please let me know if I’m reasoning about this incorrectly or missing some synchronization guarantee elsewhere in the resolver flow. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi, I think the recent parallel source discovery change introduced a concurrency regression in Patroni discovery.
lastFoundClusterMembersis a package-global map accessed from multiple goroutines afterSources.ResolveDatabases()started resolving sources concurrently.I traced unsynchronized accesses in:
internal/sources/resolver.go:83internal/sources/resolver.go:205internal/sources/resolver.go:328This can potentially cause concurrent map write panics or race detector failures when multiple continuous-discovery Patroni sources run simultaneously.
I tested a fix locally using an
RWMutex-guarded cache helper plus a concurrent regression test.If this direction looks good, I can open a PR.
Beta Was this translation helpful? Give feedback.
All reactions