Skip to content

Commit

Permalink
fix(go): fix client leak: client for the same mongodb server may be c…
Browse files Browse the repository at this point in the history
…reated multiple times (#96)

Because it need some time (maybe milliseconds to seconds) to wait `mongo.NewClient` returning a
client instance, then the client cache can be empty when other new `create(uri)` calls come, and
these new calls will also create new client instances via `mongo.NewClient`.

re #95
  • Loading branch information
genshen authored Aug 16, 2020
1 parent 6b21232 commit a60cbe2
Showing 1 changed file with 16 additions and 5 deletions.
21 changes: 16 additions & 5 deletions go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ import (
)

var (
ctx context.Context
clients sync.Map
mux = http.NewServeMux()
ctx context.Context
clients sync.Map
creationMutex sync.Mutex
mux = http.NewServeMux()
)

func runCommand(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -56,10 +57,20 @@ func runCommand(w http.ResponseWriter, r *http.Request) {
}

func create(uri string) (*mongo.Client, error) {
cached, ok := clients.Load(uri)
if ok && cached != nil {
if cached, ok := clients.Load(uri); ok && cached != nil {
return cached.(*mongo.Client), nil
}

// Use mutex to make sure there is only one active mongodb client instance for one uri.
// While with mutex, clients for different mongodb servers must be created one by one.
creationMutex.Lock()
defer creationMutex.Unlock()

// check again, if it is already created, just return.
if cached, ok := clients.Load(uri); ok && cached != nil {
return cached.(*mongo.Client), nil
}

client, err := mongo.NewClient(options.Client().ApplyURI(uri))
if err != nil {
return nil, err
Expand Down

0 comments on commit a60cbe2

Please sign in to comment.