2

I've been playing around with go for a bit now and I love it, but it seems to have a few things it does differently from other languages. So I'm writing a web app that uses MongoDb with the mgo package. I'm wondering what the best practice is for keeping a database session open for use in other packages (my models).

Feel free to correct me on any wrong ideals I might have, I've only started using GO.

Heres what I'm thinking:

package main

import(
    ds "api-v2/datastore"
)

type Log struct {
    Name string
}

func main() {
    sesh := ds.Sesh

    err = &sesh.Insert(&Log{"Ale"})
}

And in my datastore package:

package datastore

import(
    "gopkg.in/mgo.v2"
)

var Sesh = newSession()

func newSession() **mgo.Session {
    session, err := mgo.Dial("localhost")
    if err != nil {
        panic(err)
    } 

    return &session
}

Thanks!

Community
  • 1
  • 1
CloudyHLS
  • 53
  • 3
  • 1
    See if this answer is helpful. [Link](http://stackoverflow.com/a/26576589/2285935) – John S Perayil May 05 '16 at 05:43
  • You create a package that start the session as a local variable. Then create a function that get this variable and then close it when you are done. I will provide some code when I get to my desktop – CESCO May 11 '16 at 11:21

1 Answers1

3

According to mgo's documentation, https://godoc.org/gopkg.in/mgo.v2:

Every session created must have its Close method called at the end of its life time, so its resources may be put back in the pool or collected, depending on the case.

The Close() need to be called as long as the jobs are done. And the session will be returned to pool when the method is called.

Also, looking at their source code(https://github.com/go-mgo/mgo/blob/v2-unstable/session.go#L161), there are some comments on the Dial method

// This method is generally called just once for a given cluster.  Further
// sessions to the same cluster are then established using the New or Copy
// methods on the obtained session. This will make them share the underlying
// cluster, and manage the pool of connections appropriately.
//
// Once the session is not useful anymore, Close must be called to release the
// resources appropriately.

Dial method only need once for a single cluster. Use New or Copy for subsequent sessions, else you won't be beneficial from the advantage of connection pool.

--- Updated ---

I was trying to create an example but I found that the link from @John S Perayil's comment has quite a similar idea.

What I wanted to stress out is that the Dial method you should call only once during startup, it is a good idea to put it into an init method. And then you could create a method (eg, newSession) that returns session.Copy().

So this is how you would call the method:

func main() {
    session := ds.NewSession()
    defer session.Close()

    err = &session.Insert(&Log{"Ale"})
}

Somehow I noticed that you didn't invoke defer session.Close() in your code, defer will execute the code right before the ending of the execution for this method.

ch33hau
  • 2,811
  • 1
  • 15
  • 15