Skip to content

Commit a39c61a

Browse files
agviurfay
authored andcommitted
fix: protect WarningOnce cache against data race
Concurrent read/writes to outputOnceCache triggered "DATA RACE" errors during CI tests. A sync.Mutex was added to util.outputOnce to ensure safe goroutine memory access. [skip buildkite]
1 parent 9402976 commit a39c61a

1 file changed

Lines changed: 13 additions & 3 deletions

File tree

pkg/util/utils.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"regexp"
1414
"runtime"
1515
"strings"
16+
"sync"
1617
"time"
1718

1819
"github.com/ddev/ddev/pkg/exec"
@@ -22,8 +23,12 @@ import (
2223
"github.com/jedib0t/go-pretty/v6/text"
2324
)
2425

25-
// outputOnceCache is a cache to keep track of messages that have already been shown
26-
var outputOnceCache = map[string]map[string]bool{}
26+
var (
27+
// outputOnceCache is a cache to keep track of messages that have already been shown
28+
outputOnceCache = map[string]map[string]bool{}
29+
// outputOnceMutex is a mutex to protect outputOnceCache from data races
30+
outputOnceMutex sync.Mutex
31+
)
2732

2833
// outputOnce executes a function only once per unique message and function type.
2934
// It uses a SHA256 hash of the formatted message to detect duplicates.
@@ -40,17 +45,22 @@ func outputOnce(format string, a []any, fn func(string, ...any)) {
4045
msgKey := HashSalt(message)
4146
fnKey := fmt.Sprintf("%p", fn) // Use function pointer as key
4247

48+
outputOnceMutex.Lock()
4349
// Initialize the function type cache if it doesn't exist
4450
if outputOnceCache[fnKey] == nil {
4551
outputOnceCache[fnKey] = map[string]bool{}
4652
}
4753

4854
// Check if we've already executed this message for this function type
4955
if outputOnceCache[fnKey][msgKey] {
56+
outputOnceMutex.Unlock()
5057
return
5158
}
52-
// Mark as shown and execute the function
59+
// Mark as shown
5360
outputOnceCache[fnKey][msgKey] = true
61+
outputOnceMutex.Unlock()
62+
63+
// execute the function
5464
fn(format, a...)
5565
}
5666

0 commit comments

Comments
 (0)