A lightweight, generic object pool implementation in Go
go-pool is a generic, efficient object pool for Go designed to manage reusable, expensive-to-create objects such as virtual machines, interpreters, or database connections.
Instead of repeatedly allocating and destroying large objects, you can use this pool to acquire, reuse, and release instances safely and efficiently.
- Generic API – works with any object type
- Optimized for performance and low contention
- Simple, idiomatic interface
- Supports timeouts for acquiring objects
- Optional helper for automatic acquire/release management
- Embedding scripting engines (Lua, JS, etc.)
- Managing reusable network connections or sessions
- Pooling pre-initialized workers or buffers
- Any case where object creation is expensive
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/epikur-io/go-pool"
)
type PoolEntry struct{}
func (pe *PoolEntry) DoSomeWork(input string) {
log.Printf("Do some work... Input: %v\n", input)
time.Sleep(time.Second * 1)
}
func main() {
factory := func() *PoolEntry {
return &PoolEntry{}
}
pool := pool.NewPool(10, factory)
// get an entry:
{
entry, err := pool.Acquire()
if err != nil {
log.Fatalln("failed to acquire entry from pool")
}
// release entry
defer pool.Release(entry)
entry.DoSomeWork("A")
}
{
// get an entry with the given context (for timeouts and deadlines):
ctx, cancel := context.WithTimeout(context.Background(), time.Second*1)
defer cancel()
entry, err := pool.AcquireWithContext(ctx)
// release entry, since entry is nil, a new entry will be created and put into the pool
defer pool.Replace(nil)
entry.DoSomeWork("B")
if err != nil {
log.Fatalln("error:", err)
}
}
{
// automatically release entries back to the pool
err := pool.RunWithContext(context.Background(), func(ctx context.Context, e *PoolEntry) error {
// a freshly created entry will be automatically released on function exit using: `pool.Release(nil)`
e.DoSomeWork("C")
return fmt.Errorf("dummy error")
})
if err != nil {
log.Fatalln("error:", err)
}
}
}