The Go Commons Pool is a generic object pool for Golang, direct rewrite from Apache Commons Pool.
- Support custom PooledObjectFactory.
- Rich pool configuration option, can precise control pooled object lifecycle. See ObjectPoolConfig.
- Pool LIFO (last in, first out) or FIFO (first in, first out)
- Pool cap config
- Pool object validate config
- Pool object borrow block and max waiting time config
- Pool object eviction config
- Pool object abandon config
 
Configuration option table, more detail description see ObjectPoolConfig
| Option | Default | Description | 
|---|---|---|
| LIFO | true | If pool is LIFO (last in, first out) | 
| MaxTotal | 8 | The cap of pool | 
| MaxIdle | 8 | Max "idle" instances in the pool | 
| MinIdle | 0 | Min "idle" instances in the pool | 
| TestOnCreate | false | Validate when object is created | 
| TestOnBorrow | false | Validate when object is borrowed | 
| TestOnReturn | false | Validate when object is returned | 
| TestWhileIdle | false | Validate when object is idle, see TimeBetweenEvictionRuns | 
| BlockWhenExhausted | true | Whether to block when the pool is exhausted | 
| MinEvictableIdleTime | 30m | Eviction configuration,see DefaultEvictionPolicy | 
| SoftMinEvictableIdleTime | math.MaxInt64 | Eviction configuration,see DefaultEvictionPolicy | 
| NumTestsPerEvictionRun | 3 | The maximum number of objects to examine during each run evictor goroutine | 
| TimeBetweenEvictionRuns | 0 | The number of milliseconds to sleep between runs of the evictor goroutine, less than 1 mean not run | 
import (
	"context"
	"fmt"
	"strconv"
	"sync/atomic"
	"github.com/jolestar/go-commons-pool"
)
func Example_simple() {
	type myPoolObject struct {
		s string
	}
	v := uint64(0)
	factory := pool.NewPooledObjectFactorySimple(
		func(context.Context) (interface{}, error) {
			return &myPoolObject{
					s: strconv.FormatUint(atomic.AddUint64(&v, 1), 10),
				},
				nil
		})
	ctx := context.Background()
	p := pool.NewObjectPoolWithDefaultConfig(ctx, factory)
	obj, err := p.BorrowObject(ctx)
	if err != nil {
		panic(err)
	}
	o := obj.(*myPoolObject)
	fmt.Println(o.s)
	err = p.ReturnObject(ctx, obj)
	if err != nil {
		panic(err)
	}
	// Output: 1
}import (
	"context"
	"fmt"
	"strconv"
	"sync/atomic"
	"github.com/jolestar/go-commons-pool"
)
type MyPoolObject struct {
	s string
}
type MyCustomFactory struct {
	v uint64
}
func (f *MyCustomFactory) MakeObject(ctx context.Context) (*pool.PooledObject, error) {
	return pool.NewPooledObject(
			&MyPoolObject{
				s: strconv.FormatUint(atomic.AddUint64(&f.v, 1), 10),
			}),
		nil
}
func (f *MyCustomFactory) DestroyObject(ctx context.Context, object *pool.PooledObject) error {
	// do destroy
	return nil
}
func (f *MyCustomFactory) ValidateObject(ctx context.Context, object *pool.PooledObject) bool {
	// do validate
	return true
}
func (f *MyCustomFactory) ActivateObject(ctx context.Context, object *pool.PooledObject) error {
	// do activate
	return nil
}
func (f *MyCustomFactory) PassivateObject(ctx context.Context, object *pool.PooledObject) error {
	// do passivate
	return nil
}
func Example_customFactory() {
	ctx := context.Background()
	p := pool.NewObjectPoolWithDefaultConfig(ctx, &MyCustomFactory{})
	p.Config.MaxTotal = 100
    
	obj1, err := p.BorrowObject(ctx)
	if err != nil {
		panic(err)
	}
	o := obj1.(*MyPoolObject)
	fmt.Println(o.s)
	err = p.ReturnObject(ctx, obj1)
	if err != nil {
		panic(err)
	}
	// Output: 1
}For more examples please see pool_test.go and example_simple_test.go, example_customFactory_test.go.
PooledObjectFactory.MakeObject must return a pointer, not value. The following code will complain error.
p := pool.NewObjectPoolWithDefaultConfig(ctx, pool.NewPooledObjectFactorySimple(
    func(context.Context) (interface{}, error) {
        return "hello", nil
    }))
obj, _ := p.BorrowObject()
p.ReturnObject(obj)The right way is:
p := pool.NewObjectPoolWithDefaultConfig(ctx, pool.NewPooledObjectFactorySimple(
    func(context.Context) (interface{}, error) {
        s := "hello"
        return &s, nil
    }))For more examples please see example_simple_test.go.
- testify for test
The results of running the pool_perf_test is almost equal to the java version PerformanceTest
go test --perf=true
- Direct use pool.Config.xxx to change pool config
- Default config value is same as java version
- If TimeBetweenEvictionRuns changed after ObjectPool created, should call ObjectPool.StartEvictor to take effect. Java version do this on set method.
- No KeyedObjectPool (TODO)
- No ProxiedObjectPool
- No pool stats (TODO)
- Choose one open issue you want to solve, if not create one and describe what you want to change.
- Fork the repository on GitHub.
- Write code to solve the issue.
- Create PR and link to the issue.
- Make sure test and coverage pass.
- Wait maintainers to merge.
Go Commons Pool is available under the Apache License, Version 2.0.