Singleton Pattern
Refer to https://swsmile.info/post/design-pattern-singleton-pattern/ for Singleton pattern.
Using init()
functions
Package init()
functions are guaranteed to be called only once and all called from a single thread ( they’re thread-safe unless you make them multi-threaded). But that makes you dependent on boot order. And you should not write codes in an *init ( )* that you need a guarantee of execution at any given time
type A struct {
str string
}
var singleton *A
func init() {
//initialize static instance on load
singleton = &A{str: "abc"}
}
//GetInstanceA - get singleton instance pre-initialized
func GetInstanceA() *A {
return singleton
}
Lazy Load
Using sync.Once
package singleton
import "sync"
type singleton struct {
}
var (
instance *singleton
once sync.Once
)
func New() *singleton {
once.Do(func() {
instance = &singleton{}
})
return instance
}
Using sync.Mutex
package main
import (
"fmt"
"sync"
)
var lock = &sync.Mutex{}
type single struct {
}
var singleInstance *single
func getInstance() *single {
if singleInstance == nil {
lock.Lock()
defer lock.Unlock()
if singleInstance == nil {
fmt.Println("Creating single instance now.")
singleInstance = &single{}
} else {
fmt.Println("Single instance already created.")
}
} else {
fmt.Println("Single instance already created.")
}
return singleInstance
}
Reference
- https://medium.com/@ishagirdhar/singleton-pattern-in-golang-9f60d7fdab23
- https://stackoverflow.com/questions/1823286/singleton-in-go
- https://refactoring.guru/design-patterns/singleton/go/example