通用的go語言對象池:Go Commons Pool
Go commons pool是一個通用的go語言對象池,基于Java版本的Apache Commons Pool改寫。Go commons pool實現了Java版本的主要功能,改寫了大多數Java版本的測試用例,測試覆蓋率達到90%,性能測試結果和Java版本的相近,已經可以用于生產環境,于是發布1.0版本。
Go commons pool保留了Java版本的主要功能,包括:
- 自定義的 PooledObjectFactory.
- 豐富的設置選項,可以精確控制對象的生命周期。詳細參看ObjectPoolConfig。
- 對象池是否是 LIFO (后進先出) 或者是 FIFO (先進先出)
- 對象池的容量控制
- 對象池對象的驗證配置
- 獲取對象時是否阻塞以及最大等待時間配置
- 對象池對象的回收機制配置(支持后臺定時任務檢測回收)
- 對象池對象的拋棄機制配置(主要用于防止對象池對象借出后未歸還,導致對象泄露)
但不包含以下Apache commons pool的功能:
- KeyedObjectPool 實現
- ProxiedObjectPool 實現
- 對象池的統計功能
Go commons pool 最主要的應用場景是各種連接池,當前Go下的各種緩存或數據庫(比如redis/memcached)都自己實現了一個功能不太完備的連接池(比如缺少超時設置等),如果通過Go commons pool可以支持更豐富的設置。
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 TimeBetweenEvictionRunsMillis |
| BlockWhenExhausted | true | Whether to block when the pool is exhausted |
| MaxWaitMillis | -1 | Max block time, less than 0 mean indefinitely |
| MinEvictableIdleTimeMillis | 1000 * 60 * 30 | Eviction configuration,see DefaultEvictionPolicy |
| SoftMinEvictableIdleTimeMillis | math.MaxInt64 | Eviction configuration,see DefaultEvictionPolicy |
| NumTestsPerEvictionRun | 3 | The maximum number of objects to examine during each run evictor goroutine |
| TimeBetweenEvictionRunsMillis | -1 | The number of milliseconds to sleep between runs of the evictor goroutine, less than 0 mean not run |
Usage
//use create func
pool := NewObjectPoolWithDefaultConfig(NewPooledObjectFactorySimple(
func() (interface{}, error) {
return &MyPoolObject{}, nil
}))
obj, _ := pool.BorrowObject()
pool.ReturnObject(obj)
//use custom Object factory
type MyObjectFactory struct {
}
func (this *MyObjectFactory) MakeObject() (*PooledObject, error) {
return NewPooledObject(&MyPoolObject{}), nil
}
func (this *MyObjectFactory) DestroyObject(object *PooledObject) error {
//do destroy
return nil
}
func (this *MyObjectFactory) ValidateObject(object *PooledObject) bool {
//do validate
return true
}
func (this *MyObjectFactory) ActivateObject(object *PooledObject) error {
//do activate
return nil
}
func (this *MyObjectFactory) PassivateObject(object *PooledObject) error {
//do passivate
return nil
}
pool := NewObjectPoolWithDefaultConfig(new(MyObjectFactory))
pool.Config.MaxTotal = 100
obj, _ := pool.BorrowObject()
pool.ReturnObject(obj) more example please see pool_test.go and example_test.go
Note
PooledObjectFactory.MakeObject must return a pointer, not value. The following code will complain error.
pool := NewObjectPoolWithDefaultConfig(NewPooledObjectFactorySimple(
func() (interface{}, error) {
return "hello", nil
}))
obj, _ := pool.BorrowObject()
pool.ReturnObject(obj) The right way is:
pool := NewObjectPoolWithDefaultConfig(NewPooledObjectFactorySimple(
func() (interface{}, error) {
var stringPointer = new(string)
*stringPointer = "hello"
return stringPointer, nil
})) more example please see example_test.go
Dependency
- testify for test
PerformanceTest
The results of running the pool_perf_test is almost equal to the java version PerformanceTest
go test --perf=true
For Apache commons pool user
- Direct use pool.Config.xxx to change pool config
- Default config value is same as java version
- If TimeBetweenEvictionRunsMillis changed after ObjectPool created, should call ObjectPool.StartEvictor to take effect. Java version do this on set method.
- No KeyedObjectPool
- 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.