Singlet provides threadsafe, generic singletons for Golang.
The common pattern of using sync.Once
to implement a global singleton doesn't work well when the singleton value includes a generic type, since type arguments may not be available at a global level. Singlet provides a solution, allowing you to create threadsafe, generic singletons, anywhere in your code.
To use singlet, first create a Singleton
. Then call GetOrDo
which will create and store a value in the Singleton
, if one doesn't already exist, by calling the provided func
, else it will return the existing value:
var s = &singlet.Singleton{}
cache1, _ := singlet.GetOrDo(s, cache.New[int])
cache2, _ := singlet.GetOrDo(s, cache.New[int]) // cache.New is only called once
if cache1 != cache2 {
panic("caches should be equal")
}
You can also get a previously created value for a Singleton
:
cache, _ := singlet.Get[*Cache[int]](singleton)
Calling Get
or GetOrDo
for a result type that doesn't match the previously stored result type for a Singleton
will result in an ErrTypeMismatch
:
singlet.GetOrDo(s, cache.New[int])
singlet.Get[string](s) // Returns ErrTypeMismatch
Copyright Jonathan Halterman. Released under the Apache 2.0 license.