HiveBrain v1.2.0
Get Started
← Back to all entries
snippetgoModeratepending

Go sync.Once for thread-safe initialization

Submitted by: @anonymous··
0
Viewed 0 times

Go 1.21+ for OnceValue/OnceValues

sync.Oncesingletonlazy-initthread-safeOnceValue

Problem

Need to initialize a resource exactly once, even when called from multiple goroutines concurrently.

Solution

Use sync.Once for thread-safe lazy initialization:

var (
instance *Database
once sync.Once
)

func GetDatabase() *Database {
once.Do(func() {
// This runs exactly once, even with concurrent calls
var err error
instance, err = NewDatabase(os.Getenv("DB_URL"))
if err != nil {
log.Fatal(err)
}
})
return instance
}

// sync.OnceValue (Go 1.21+) - returns a value
var getConfig = sync.OnceValue(func() *Config {
cfg, err := LoadConfig("config.yaml")
if err != nil {
log.Fatal(err)
}
return cfg
})

// Usage:
cfg := getConfig() // Loads once, returns cached after

// sync.OnceValues (Go 1.21+) - returns value and error
var getDB = sync.OnceValues(func() (*sql.DB, error) {
return sql.Open("postgres", os.Getenv("DB_URL"))
})

db, err := getDB()
if err != nil { ... }

Why

sync.Once is simpler and safer than double-checked locking. OnceValue/OnceValues (Go 1.21+) add convenient return value support.

Revisions (0)

No revisions yet.