Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

session: add example concurrent usage #78

Merged
merged 1 commit into from
Jan 15, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/x509"
"io/ioutil"
"net"
"sync"
)

func ExampleCredential_x509Authentication() {
Expand Down Expand Up @@ -86,3 +87,50 @@ func ExampleCredential_x509Authentication() {
// You should actually check the error code at each step.
_ = err
}

func ExampleSession_concurrency() {
// This example shows the best practise for concurrent use of a mgo session.
//
// Internally mgo maintains a connection pool, dialling new connections as
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it dialing or dialling ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its dialling, weird eh?

// required.
//
// Some general suggestions:
// - Define a struct holding the original session, database name and
// collection name instead of passing them explicitly.
// - Define an interface abstracting your data access instead of exposing
// mgo to your application code directly.
// - Limit concurrency at the application level, not with SetPoolLimit().

// This will be our concurrent worker
var doStuff = func(wg *sync.WaitGroup, session *Session) {
defer wg.Done()

// Copy the session - if needed this will dial a new connection which
// can later be reused.
//
// Calling close returns the connection to the pool.
conn := session.Copy()
defer conn.Close()

// Do something(s) with the connection
_, _ = conn.DB("").C("my_data").Count()
}

///////////////////////////////////////////////

// Dial a connection to Mongo - this creates the connection pool
session, err := Dial("localhost:40003/my_database")
if err != nil {
panic(err)
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you could authenticate here to show that all copied sessions inherit the authorization status of the parent session?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good idea - but I will leave a comment and update the documentation for Clone. To add the auth in the example the test harness initialisation code would have to be modified.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it's already documented behaviour of Copy():

Copy works just like New, but preserves the exact authentication information from the original session.

// Concurrently do things, passing the session to the worker
wg := &sync.WaitGroup{}
for i := 0; i < 10; i++ {
wg.Add(1)
go doStuff(wg, session)
}
wg.Wait()

session.Close()
}