Documentation
¶
Overview ¶
Package pool provides a generic connection pooling implementation.
The pool manages reusable connections of any type, handling concurrent connection requests, usage tracking, and automatic cleanup of idle connections.
Basic Usage ¶
The pool is generic over two type parameters:
- K: the key type (must be comparable for use as map key)
- V: the value type (must implement Close() error)
Example with a simple closer:
type MyConn struct { /* ... */ }
func (c *MyConn) Close() error { return nil }
connector := pool.ConnectorFunc[string, *MyConn](func(ctx context.Context, key string) (*MyConn, error) {
return &MyConn{}, nil
})
p := pool.New(connector)
defer p.Close()
lease, err := p.Acquire(ctx, "connection-key")
if err != nil {
return err
}
defer lease.Release()
conn := lease.Value()
// use conn...
Scrapper Pool ¶
For scrapper.Scrapper specifically, use ScrapperPool which returns a wrapper that implements scrapper.Scrapper directly:
connector := pool.ConnectorFunc[string, scrapper.Scrapper](func(ctx context.Context, connId string) (scrapper.Scrapper, error) {
// Create your scrapper...
return myScrapper, nil
})
p := pool.NewScrapperPool(connector)
defer p.Close()
scr, err := p.Acquire(ctx, "my-connection")
if err != nil {
return err
}
defer scr.Close() // Returns to pool, doesn't actually close
rows, err := scr.QueryCatalog(ctx)
Custom Key Types ¶
Any comparable type can be used as a key:
type ConnectionKey struct {
Host string
Port int
User string
}
connector := pool.ConnectorFunc[ConnectionKey, *sql.DB](...)
p := pool.New(connector)
lease, _ := p.Acquire(ctx, ConnectionKey{Host: "localhost", Port: 5432, User: "admin"})
Configuration ¶
The pool supports several options:
p := pool.New(connector,
pool.WithCleanerInterval[K, V](30 * time.Second), // How often to check for idle connections
pool.WithMaxIdleDuration[K, V](5 * time.Minute), // How long before idle connections are closed
pool.WithHooks[K, V](pool.Hooks[K, V]{
OnConnecting: func(ctx context.Context, key K) { /* ... */ },
OnConnected: func(ctx context.Context, key K, value V) { /* ... */ },
OnRelease: func(ctx context.Context, key K, value V) { /* ... */ },
OnEvict: func(ctx context.Context, key K, value V) { /* ... */ },
}),
)
Connection Lifecycle ¶
1. First Acquire(ctx, key): Creates new connection via Connector.Connect() 2. Subsequent Acquire(ctx, key): Reuses existing connection (increments usage) 3. Concurrent Acquire(ctx, key): Waits for in-flight connection 4. Release()/Close(): Decrements usage, marks connection as idle when usage=0 5. GC cycle: Closes connections idle longer than MaxIdleDuration 6. Pool.Close(): Closes all connections
Package pool provides a generic connection pooling implementation.
The pool manages reusable connections of any type, handling concurrent connection requests, usage tracking, and automatic cleanup of idle connections.
Example usage:
connector := pool.ConnectorFunc[string, *sql.DB](func(ctx context.Context, dsn string) (*sql.DB, error) {
return sql.Open("postgres", dsn)
})
p := pool.New(connector)
defer p.Close()
lease, err := p.Acquire(ctx, "postgres://localhost/mydb")
if err != nil {
return err
}
defer lease.Release()
db := lease.Value()
// use db...
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Closer ¶
type Closer interface {
Close() error
}
Closer is the interface for resources that can be closed.
type Connector ¶
type Connector[K comparable, V Closer] interface { Connect(ctx context.Context, key K) (V, error) }
Connector creates connections of type V keyed by K.
type ConnectorFunc ¶
type ConnectorFunc[K comparable, V Closer] func(ctx context.Context, key K) (V, error)
ConnectorFunc is a function adapter for Connector.
type Hooks ¶
type Hooks[K comparable, V Closer] struct { // OnConnecting is called when a new connection attempt starts. OnConnecting func(ctx context.Context, key K) // OnConnected is called when a new connection is established. OnConnected func(ctx context.Context, key K, value V) // OnConnectError is called when a connection attempt fails. OnConnectError func(ctx context.Context, key K, err error) // OnAcquire is called when an existing connection is reused. OnAcquire func(ctx context.Context, key K, value V) // OnWaiting is called when waiting for an in-flight connection. OnWaiting func(ctx context.Context, key K) // OnRelease is called when a connection is released back to the pool. OnRelease func(ctx context.Context, key K, value V) // OnEvict is called when a connection is evicted from the pool. OnEvict func(ctx context.Context, key K, value V) // FormatKey formats a key for logging. If nil, fmt.Sprintf("%v", key) is used. FormatKey func(key K) string }
Hooks provides callbacks for pool lifecycle events. All callbacks are optional.
type Lease ¶
type Lease[K comparable, V Closer] struct { // contains filtered or unexported fields }
Lease represents a borrowed connection from the pool. It must be released when done by calling Release() or Close().
func (*Lease[K, V]) Close ¶
Close is an alias for Release. It satisfies the Closer interface, allowing Lease to be used with defer.
func (*Lease[K, V]) Release ¶
func (l *Lease[K, V]) Release()
Release returns the connection to the pool. It is safe to call Release multiple times.
type Option ¶
type Option[K comparable, V Closer] func(*Pool[K, V])
Option configures a Pool.
func WithCleanerInterval ¶
func WithCleanerInterval[K comparable, V Closer](d time.Duration) Option[K, V]
WithCleanerInterval sets the interval between cleanup cycles. Default: 30 seconds.
func WithHooks ¶
func WithHooks[K comparable, V Closer](hooks Hooks[K, V]) Option[K, V]
WithHooks sets lifecycle hooks for the pool.
func WithMaxIdleDuration ¶
func WithMaxIdleDuration[K comparable, V Closer](d time.Duration) Option[K, V]
WithMaxIdleDuration sets the maximum time a connection can be idle before eviction. Default: 5 minutes.
type Pool ¶
type Pool[K comparable, V Closer] struct { // contains filtered or unexported fields }
Pool manages a pool of reusable connections.
func New ¶
func New[K comparable, V Closer](connector Connector[K, V], opts ...Option[K, V]) *Pool[K, V]
New creates a new Pool with the given connector and options.
func (*Pool[K, V]) Acquire ¶
Acquire obtains a connection from the pool. If an existing connection is available, it is reused. If a connection is being established, this call waits for it. Otherwise, a new connection is created.
The returned Lease must be released when done, either by calling Release() or Close(). Failing to release the lease will prevent the connection from being reused or cleaned up.
func (*Pool[K, V]) Close ¶
Close closes the pool and all connections. After Close is called, Acquire will return an error.
type ScrapperPool ¶
type ScrapperPool[K comparable] struct { // contains filtered or unexported fields }
ScrapperPool is a specialized pool for scrapper.Scrapper connections.
func NewScrapperPool ¶
func NewScrapperPool[K comparable](connector Connector[K, scrapper.Scrapper], opts ...Option[K, scrapper.Scrapper]) *ScrapperPool[K]
NewScrapperPool creates a new pool for scrapper.Scrapper connections.
func (*ScrapperPool[K]) Acquire ¶
Acquire obtains a scrapper from the pool, returning a wrapper that implements scrapper.Scrapper. When Close() is called on the wrapper, the connection is released back to the pool rather than being closed.
func (*ScrapperPool[K]) Close ¶
func (p *ScrapperPool[K]) Close() error
Close closes the pool and all connections.
func (*ScrapperPool[K]) Pool ¶
func (p *ScrapperPool[K]) Pool() *Pool[K, scrapper.Scrapper]
Pool returns the underlying generic pool.
func (*ScrapperPool[K]) Usage ¶
func (p *ScrapperPool[K]) Usage() map[K]int
Usage returns the current usage count for each connection.