Notes: Go Design Patterns - Singleton Pattern
This blog contains Singleton design pattern implementation by creating exactly one MongoDB connection
Singleton pattern makes sure that only one instance of an object is created. This pattern is used to create DB connections or connections with other external systems. We'll see its usage by trying to create a singleton MongoDB connection:
func getNewMongoClient() *mongo.Client {
if mongoClient == nil {
once.Do(
mongoConnect,
)
} else {
fmt.Println("mongo client already created.")
}
return mongoClient
}
Here once.Do
makes sure that this section of the code gets executed only one time no matter how many times it is called. We could have used mutex locks as well but the right way to implement a singleton pattern in Go is to use the sync package’s Once.Do
function. This function makes sure that your specified code is executed only once and never more than once.
To run the example code, first, start a mongo server using docker: docker run -d -p 27017:27017 --name mongo-server mongo:latest
Now, once you run this code, you'll see that only the first getNewMongoClient()
will return success while subsequent calls will fail.
Working code to test:
package main
import (
"context"
"fmt"
"log"
"sync"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var once sync.Once
var mongoClient *mongo.Client
// start mongo server by using this command:
// docker run -d -p 27017:27017 --name mongo-server mongo:latest
func mongoConnect() {
var err error
// Set client options
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
// Connect to MongoDB
mongoClient, err = mongo.Connect(context.TODO(), clientOptions)
if err != nil {
log.Fatal(err)
}
// Check the connection
err = mongoClient.Ping(context.TODO(), nil)
if err != nil {
log.Fatal(err)
}
fmt.Println("connected to mongo!")
}
func getNewMongoClient() *mongo.Client {
if mongoClient == nil {
once.Do(
mongoConnect,
)
} else {
fmt.Println("mongo client already created.")
}
return mongoClient
}
func main() {
getNewMongoClient()
getNewMongoClient()
getNewMongoClient()
getNewMongoClient()
}