pool

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 18, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package pool is a small, dependency-free connection pool for *pgz.Client.

Design choices:

  • Bounded by MaxConns. Acquire() blocks (with context) when full.
  • Idle conns live on a LIFO stack so the warm ones stay warm.
  • Background reaper closes conns idle longer than IdleTimeout.
  • On a query error, the caller releases with Discard() so the broken conn does not return to the pool.
  • All goroutines exit on Close().

Index

Constants

This section is empty.

Variables

View Source
var ErrClosed = errors.New("pool: closed")

ErrClosed is returned by Acquire after Close.

Functions

This section is empty.

Types

type Config

type Config struct {
	pgz.Config

	MaxConns       int           // default 16
	MinIdle        int           // default 0
	IdleTimeout    time.Duration // default 5m
	AcquireTimeout time.Duration // default unbounded; per-call ctx wins
	HealthCheck    time.Duration // background reaper interval; default 30s
	// PingAfterIdle is the threshold above which Acquire pings the
	// idle connection before returning it. Default: 30s. Set to 0 to
	// disable. Helps survive PgBouncer's server_idle_timeout (default
	// 600s) and middlebox NAT timeouts.
	PingAfterIdle time.Duration
	// MaxConnLifetime caps the total wall-clock lifetime of a pooled
	// connection. Past this, Acquire closes and reopens. Defaults to 1h.
	// Bound the long-tail growth of server-side state (prepared stmts,
	// catalog caches, etc.) on long-lived backends.
	MaxConnLifetime time.Duration

	// MaxInFlightBuffers caps the number of scratch buffers checked out
	// from the internal buffer pool at any instant. Applied process-wide
	// (the buffer pool is a package-level singleton). 0 = unbounded.
	// Useful under extreme bursts where 32 KiB × N-thousand concurrent
	// queries would otherwise balloon the pool's backing slab. When the
	// cap is hit, Get falls back to plain make() and bypasses the pool;
	// callers always receive a usable buffer.
	MaxInFlightBuffers int
}

Config configures the pool. Zero values are sane defaults.

type Conn

type Conn struct {
	*pgz.Client
	// contains filtered or unexported fields
}

Conn is the handle returned by Acquire. Always call Release or Discard.

func (*Conn) Discard

func (c *Conn) Discard()

Discard closes the connection and decrements the open count. Use this when an operation on the connection failed in a way that leaves it in an unknown state (network error, mid-query cancellation, etc.).

func (*Conn) Release

func (c *Conn) Release()

Release returns the connection to the pool.

type Pool

type Pool struct {
	// contains filtered or unexported fields
}

Pool is a thread-safe pool of *pgz.Client.

func New

func New(cfg Config) (*Pool, error)

New starts a pool. Min idle connections are created eagerly.

func (*Pool) Acquire

func (p *Pool) Acquire(ctx context.Context) (*Conn, error)

Acquire returns a connection from the pool, blocking up to ctx until one is available or the pool is at capacity. Acquire transparently handles:

  • max-lifetime expiry (the conn is closed and a fresh one is opened)
  • long-idle ping (catches conns the network silently dropped, e.g. after PgBouncer's server_idle_timeout)
  • one transparent retry on any failure of the above checks

The retry is bounded — we never loop more than a handful of times so a hard backend failure surfaces fast.

func (*Pool) Close

func (p *Pool) Close() error

Close drains the pool and closes every idle connection. Outstanding Acquire callers receive ErrClosed.

func (*Pool) Drain

func (p *Pool) Drain(ctx context.Context) error

Drain stops accepting new Acquire calls and waits for in-flight connections to be Released. Idle connections are closed immediately. Returns ctx.Err() if ctx expires before all in-flight conns return. After a successful Drain, Close is a no-op other than cleanup.

Typical rolling-deploy pattern:

ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := pool.Drain(ctx); err != nil { /* log; forced shutdown */ }
pool.Close()

func (*Pool) Stats

func (p *Pool) Stats() Stats

func (*Pool) WaitIdle

func (p *Pool) WaitIdle(ctx context.Context) error

WaitIdle blocks until the pool has no in-flight (acquired) connections. Handy in tests and between rolling-deploy phases. Returns immediately if the pool is already idle.

type Stats

type Stats struct {
	Open    int
	Idle    int
	InUse   int
	Waiting int
	Max     int
}

Stats is a snapshot of pool counters.

Jump to

Keyboard shortcuts

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