Skip to content

Simpler code to cache value#2808

Closed
dgageot wants to merge 1 commit into
docker:mainfrom
dgageot:simpler-singleton
Closed

Simpler code to cache value#2808
dgageot wants to merge 1 commit into
docker:mainfrom
dgageot:simpler-singleton

Conversation

@dgageot
Copy link
Copy Markdown
Member

@dgageot dgageot commented May 17, 2026

No description provided.

Signed-off-by: David Gageot <david.gageot@docker.com>
@dgageot dgageot requested a review from a team as a code owner May 17, 2026 16:33
Copy link
Copy Markdown

@docker-agent docker-agent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assessment: 🟡 NEEDS ATTENTION

One confirmed medium-severity data race introduced by the refactor.

Comment thread pkg/userid/userid.go
if cached != "" {
return cached
}
func ResetForTests() {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MEDIUM] Data race: unsynchronised write to Get in ResetForTests() vs concurrent reads

ResetForTests() assigns a fresh sync.OnceValue to the package-level variable Get without any synchronisation. Meanwhile, parallel tests (e.g. TestHeaders uses t.Parallel()) or the HTTP client may be reading Get to call it. Writing to a shared variable from one goroutine while another goroutine reads it is a data race under the Go memory model — go test -race will flag it.

The old implementation avoided this by holding mu inside ResetForTests() before clearing cached. The new implementation has no equivalent protection on the variable itself.

Suggested fix: protect the variable with a sync.RWMutex, use sync/atomic (atomic.Value or a pointer), or — simplest for a test-only reset — guard the write and read with a mutex:

var getMu sync.RWMutex
var getOnce = sync.OnceValue(get)

func Get() string {
    getMu.RLock()
    f := getOnce
    getMu.RUnlock()
    return f()
}

func ResetForTests() {
    getMu.Lock()
    getOnce = sync.OnceValue(get)
    getMu.Unlock()
}

@dgageot dgageot closed this May 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants