mgopool

package module
v0.0.0-...-1876329 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 8, 2020 License: MIT Imports: 2 Imported by: 0

README

mgopool
GoDoc Build Status

Package mgopool provides buffer implementations around mgo.Session (v2).

go get github.com/globalsign/mgo
go get github.com/vsco/mgopool

With mgo, an initial session is created with the server, and then either a Copy or Clone of that initial session is used for each unit of work (HTTP request handler, worker loop, etc.), which is closed upon completion. This allows mgo to efficiently manage a pool of sockets between those sessions; however, it also results in the underlying sockets to constantly log in and out of the Mongo cluster.

mgopool avoids this issue by creating a Pool of copies from the initial session, storing them in a free list. Work units request an existing copy (or one is created if it doesn't exist) and then return it to the pool on completion. Both a leaky and capped version of the Pool is available, depending on need.

Example Usage

func Example() {
  // create the initial mgo.Session, defer closing it
  initial, _ := mgo.Dial("127.0.0.1")
  defer initial.Close()

  // create a new leaky pool with size of 3
  pool := mgopool.NewLeaky(initial, 3)
  defer pool.Close()

  wg := sync.WaitGroup{}

  // create a few workers to utilize the sessions in the pool
  for i := 0; i < 3; i++ {
    wg.Add(1)

    go func() {
      for j := 0; j < 2; j++ {
        // get a session from the pool
        session := pool.Get()

        // do something with that session, refresh it if there is an error
        if err := doSomething(session); err != nil {
          session.Refresh()
        }

        // return the session to the pool
        pool.Put(session)
      }
      wg.Done()
    }()
  }

  // wait for the workers to complete
  wg.Wait()

  // Output:
  // foobar
  // foobar
  // foobar
  // foobar
  // foobar
  // foobar
}

func doSomething(s *mgo.Session) error {
  fmt.Println("foobar")
  return s.Ping()
}

Testing

Testing mgopool requires a running Mongo cluster. The default Mongo host is used (127.0.0.1:27017) and can be overridden by setting the MONGO_HOST env variable. Execute the tests with the following command from the project root:

script/test

License

The MIT License (MIT)

Copyright (c) 2016 Visual Supply, Co.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Documentation

Overview

Package mgopool provides buffer implementations around mgo.Session (v2).

With mgo, an initial session is created with the server, and then either a copy or clone of that initial session is used for each unit of work (HTTP request handler, worker loop, etc.), which is closed upon completion. This allows mgo to efficiently manage a pool of sockets between those sessions; however, this results in the underlying sockets to constantly log in and out of the Mongo cluster.

mgopool avoids this issue by creating a Pool of copies from the initial session, storing them in a free list. Work units request an existing copy (or one is created if it doesn't exist) and then return it to the pool on completion. Both a leaky and capped version of the Pool is available, depending on need.

Example
package main

import (
	"os"

	"sync"

	"fmt"

	"github.com/globalsign/mgo"
)

func main() {
	host := os.Getenv("MONGO_HOST")

	// create the initial mgo.Session, defer closing it
	initial, _ := mgo.Dial(host)
	defer initial.Close()

	// create a new leaky pool with size of 3
	pool := NewLeaky(initial, 3)
	defer pool.Close()

	wg := sync.WaitGroup{}

	// create a few workers to utilize the sessions in the pool
	for i := 0; i < 3; i++ {
		wg.Add(1)

		go func() {
			for j := 0; j < 2; j++ {
				// get a session from the pool
				session := pool.Get()

				// do something with that session, refresh it if there is an error
				if err := doSomething(session); err != nil {
					session.Refresh()
				}

				// return the session to the pool
				pool.Put(session)
			}
			wg.Done()
		}()
	}

	// wait for the workers to complete
	wg.Wait()

}

func doSomething(s *mgo.Session) error {
	fmt.Println("foobar")
	return s.Ping()
}
Output:

foobar
foobar
foobar
foobar
foobar
foobar

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Pool

type Pool interface {
	// Get returns a *mgo.Session from the Pool. If there are no free sessions, a new one is copied from the initial
	// Session. If the Pool is capped and all sessions have been retrieved, Get will block until a session is returned to
	// with Put.
	Get() *mgo.Session

	// Put releases an *mgo.Session back into the Pool. Only healthy sessions (or nil) should be returned to the pool. If
	// a session is errors, Refresh should be called before releasing it to the Pool.
	Put(*mgo.Session)

	// Used is the total number of outstanding leases associated with this Pool.
	// Note, this is just a snapshot of the used leased at the time this method was invoked
	Used() int

	// Close drains the Pool, closing all held sessions. The initial session is not closed by this method. Calling Get or
	// Put on a closed pool will result in a panic.
	Close()
}

The Pool interface describes the mechanisms for retrieving and releasing mgo.Sessions. The pool should be used in place of calling Copy/Clone and Close on mgo.Session directly.

func NewCapped

func NewCapped(initial *mgo.Session, size int) Pool

NewCapped creates a capped Pool of sessions copied from initial. Get on a capped Pool will block after size sessions have been retrieved until one is Put back in.

func NewLeaky

func NewLeaky(initial *mgo.Session, size int) Pool

NewLeaky creates a leaky Pool of sessions copied from initial. A maximum of size sessions will be held in the free list, but the Pool will not block calls to Get. Releasing excess sessions to the pool are automatically Closed and removed.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL