Skip to content

Instantly share code, notes, and snippets.

@euclid1990
Last active October 27, 2021 10:06
Show Gist options
  • Save euclid1990/d59d9301ecb6f4a2b0d08d00f4820faf to your computer and use it in GitHub Desktop.
Save euclid1990/d59d9301ecb6f4a2b0d08d00f4820faf to your computer and use it in GitHub Desktop.
Go - Singleton Pattern
package main
import (
"fmt"
"sync"
)
var (
doOnce sync.Once
doLock = &sync.Mutex{}
instance *db
)
type db struct {
Connection string
}
func setInstance(connection string) {
instance = &db{Connection: connection}
fmt.Println("Singleton instance has been created.")
}
func (d *db) GetConnection() string {
return d.Connection
}
func GetInstanceByDoOnce(connection string) *db {
doOnce.Do(func() {
setInstance(connection)
})
return instance
}
func GetInstanceByDoLock(connection string) *db {
if instance == nil {
doLock.Lock()
defer doLock.Unlock()
setInstance(connection)package main
import (
"fmt"
"io"
"os"
"sync"
)
var (
instance *db
doOnce sync.Once
doLock = &sync.Mutex{}
out io.Writer = os.Stdout
)
type db struct {
Connection string
}
func setInstance(connection string) {
instance = &db{Connection: connection}
fmt.Fprintln(out, "Singleton instance has been created.")
}
func (d *db) GetConnection() string {
return d.Connection
}
func GetInstanceByDoOnce(connection string) *db {
doOnce.Do(func() {
setInstance(connection)
})
return instance
}
func GetInstanceByDoLock(connection string) *db {
if instance == nil {
doLock.Lock()
defer doLock.Unlock()
setInstance(connection)
}
return instance
}
func main() {
connectionString := "[email protected]:3306/main-schema"
GetInstanceByDoOnce(connectionString)
GetInstanceByDoLock(connectionString)
}
}
return instance
}
func main() {
connectionString := "[email protected]:3306/main-schema"
GetInstanceByDoOnce(connectionString)
GetInstanceByDoLock(connectionString)
}
package main
import (
"bytes"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)
type SingletonTestSuite struct {
suite.Suite
}
func (suite *SingletonTestSuite) SetupTest() {
instance = nil
}
func (suite *SingletonTestSuite) TestDbGetConnection() {
connectionString := "[email protected]:3306/main-schema"
db := &db{Connection: connectionString}
assert.Equal(suite.T(), connectionString, db.GetConnection())
}
func (suite *SingletonTestSuite) TestSetInstance() {
bak := out
out = new(bytes.Buffer)
defer func() { out = bak }()
setInstance("[email protected]:3306/main-schema")
assert.Equal(suite.T(), "Singleton instance has been created.\n", out.(*bytes.Buffer).String())
}
func (suite *SingletonTestSuite) TestGetInstanceByDoOnce() {
bak := out
out = new(bytes.Buffer)
defer func() { out = bak }()
connectionStringFirst := "[email protected]:3306/main-schema-do-one-first"
connectionStringSecond := "[email protected]:3306/main-schema-do-one-second"
instanceFirst := GetInstanceByDoOnce(connectionStringFirst)
instanceSecond := GetInstanceByDoOnce(connectionStringSecond)
assert.Equal(suite.T(), connectionStringFirst, instanceFirst.GetConnection())
assert.Equal(suite.T(), connectionStringFirst, instanceSecond.GetConnection())
}
func (suite *SingletonTestSuite) TestGetInstanceByDoLock() {
bak := out
out = new(bytes.Buffer)
defer func() { out = bak }()
connectionStringFirst := "[email protected]:3306/main-schema-do-lock-first"
connectionStringSecond := "[email protected]:3306/main-schema-do-lock-second"
instanceFirst := GetInstanceByDoLock(connectionStringFirst)
instanceSecond := GetInstanceByDoLock(connectionStringSecond)
assert.Equal(suite.T(), connectionStringFirst, instanceFirst.GetConnection())
assert.Equal(suite.T(), connectionStringFirst, instanceSecond.GetConnection())
}
func TestSingletonTestSuite(t *testing.T) {
suite.Run(t, new(SingletonTestSuite))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment