GitHub - jolestar/go-commons-pool: a generic object pool for golang (original) (raw)
Go Commons Pool
The Go Commons Pool is a generic object pool for Golang, direct rewrite from Apache Commons Pool.
Features
- 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
Pool Configuration Option
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 |
Usage
Use Simple Factory
import ( "context" "fmt" "strconv" "sync/atomic"
"github.com/jolestar/go-commons-pool/v2")
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}
Use Custom Factory
import ( "context" "fmt" "strconv" "sync/atomic"
"github.com/jolestar/go-commons-pool/v2")
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.
Note
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.
Dependency
- testify for test
PerformanceTest
The results of running the pool_perf_test is almost equal to the java version PerformanceTest
For Apache commons pool user
- 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)
FAQ
How to contribute
- 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.
中文文档
License
Go Commons Pool is available under the Apache License, Version 2.0.