pool

package
v0.9.0-rc4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 14, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

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.

func (ConnectorFunc[K, V]) Connect

func (f ConnectorFunc[K, V]) Connect(ctx context.Context, key K) (V, error)

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

func (l *Lease[K, V]) Close() error

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.

func (*Lease[K, V]) Released

func (l *Lease[K, V]) Released() bool

Released returns true if the lease has been released.

func (*Lease[K, V]) Value

func (l *Lease[K, V]) Value() V

Value returns the underlying connection. Returns the zero value if the lease has been released.

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

func (p *Pool[K, V]) Acquire(ctx context.Context, key K) (*Lease[K, V], error)

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

func (p *Pool[K, V]) Close() error

Close closes the pool and all connections. After Close is called, Acquire will return an error.

func (*Pool[K, V]) GC

func (p *Pool[K, V]) GC()

GC triggers a garbage collection cycle to clean up idle connections.

func (*Pool[K, V]) Usage

func (p *Pool[K, V]) Usage() map[K]int

Usage returns the current usage count for each connection in the pool.

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

func (p *ScrapperPool[K]) Acquire(ctx context.Context, key K) (scrapper.Scrapper, error)

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]) GC

func (p *ScrapperPool[K]) GC()

GC triggers a garbage collection cycle.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL