Skip to main content

Crate connpool

Crate connpool 

Source
Expand description

connpool — a generic connection pool for Rust, dependency-free (blocking) with an optional async pool behind the tokio feature.

It pools anything a small user-supplied ConnectionFactory can create, validate, reset and close — DB drivers, HTTP clients, SSH sessions, raw sockets. The pool knows nothing about your connection except what the factory tells it.

§Layers (each only depends on the ones above it)

core           errors, clocks, connection bookkeeping, timeout math
resilience     circuit breaker, retry/backoff
policy         PoolConfig + the pure retirement rules
factories      ConnectionFactory: the seam users implement to pool anything
observability  listeners + stats
pools          ConnectionPool, AsyncConnectionPool, PoolRegistry

connpool is the Rust member of poolyglot: one pooling model implemented per language, kept API-parallel. Field names, event names, defaults, and CloseReason/BreakerState wire values are identical to the Python, C#, Java, Go and TypeScript implementations — switching languages is a syntax change, not a model change.

§Example

use connpool::{ConnectionPool, FnFactory, PoolConfig, Timeout};
use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};

// A toy "connection": a unique id behind an Arc so clones share identity.
let next = Arc::new(AtomicU64::new(0));
let factory = FnFactory::new({
    let next = next.clone();
    move || Ok::<_, connpool::FactoryError>(Arc::new(next.fetch_add(1, Ordering::SeqCst)))
});

let pool = ConnectionPool::new(factory, PoolConfig { max_size: 4, ..Default::default() }, None)
    .expect("valid config");
let conn = pool.acquire(Timeout::Unset).expect("acquire");
// ... use conn ...
pool.release(conn).expect("release");

Connections are tracked by value identity, so T must be Clone + Eq + Hash — use a cheap handle type such as Arc<Conn> or an id (the direct analog of the Go port’s comparable constraint).

Structs§

AsyncConnectionPool
A tokio-based, cancel-safe connection pool. Cheaply clonable (clones share one pool).
AsyncFnFactory
An AsyncConnectionFactory built from closures returning [BoxFuture]s.
AsyncPoolRegistry
Hands out one AsyncConnectionPool per key, built on first use. Lazy: pools are not opened automatically.
BreakerConfig
Configuration for a CircuitBreaker.
CircuitBreaker
A thread-safe circuit breaker. Usage: before_call -> do work -> record_success / record_failure / record_abort.
ConnectionPool
A thread-safe, blocking connection pool. Cheaply clonable (clones share one pool).
FnFactory
A ConnectionFactory built from plain closures. Unset hooks fall back to the trait defaults.
ManualClock
A fake clock for tests: time moves only when you tell it to; sleeping just advances it. Use 1000.0 as the start to match the other languages’ default.
PoolConfig
An immutable, validated pool configuration. Build one with struct-update syntax from PoolConfig::default, then hand it to a pool — which re-validates it.
PoolOptions
Options for constructing a pool. All fields are optional.
PoolRegistry
Hands out one ConnectionPool per key, built on first use. It is lazy: a pool is created on first access and is NOT opened, so it does no background maintenance unless you open it yourself.
PoolStats
An immutable snapshot of pool metrics. The keys of PoolStats::to_dictionary are snake_case wire strings identical across every poolyglot language.
PooledConnection
A raw connection plus pool bookkeeping. Instances are tracked by the pool; listeners receive &PooledConnection<T>. The raw connection is reachable via PooledConnection::raw.
RetryPolicy
How to retry factory.create(): exponential backoff with jitter.
SystemClock
Real wall-clock time (the default). Anchored at construction so monotonic starts near 0.
SystemRng
The default Rng: a SplitMix64 PRNG seeded from the standard library’s process-randomized hasher state. Non-cryptographic — it exists only to jitter timings.

Enums§

BreakerState
The circuit breaker’s state-machine position.
CloseReason
Why a connection left the pool. The string values (CloseReason::as_str) are wire values kept identical across every poolyglot language — do not localize them.
IdleStrategy
Which idle connection is reused first.
PoolError
Every error the pool raises. Mirrors the PoolError base type of the other languages; each variant corresponds to a sibling error class.
StatValue
A value in the PoolStats::to_dictionary wire representation.
Timeout
The per-call acquire timeout. One of three things:

Constants§

VERSION
The released version of this crate, kept in lock-step with the root VERSION file.

Traits§

AsyncConnectionFactory
Implement this to pool anything asynchronously. create must return a distinct object each call (tracked by value identity).
Clock
A monotonic time source. The pool uses the injected clock for logical time (connection age, idle time, breaker recovery, retry backoff); real-time blocking in the async pool is driven by the runtime, not the clock (exactly as Python’s asyncio.timeout ignores the injected clock).
ConnectionFactory
Implement this to pool anything (DB driver, HTTP client, SSH session, socket…) — or build one from closures via FnFactory.
PoolListener
Observability hooks for metrics, tracing, logging. Implement the ones you care about; all default to no-ops. Hooks run synchronously on the calling thread, outside the pool’s lock, so keep them fast. Panics raised by a listener are caught and logged — a broken metrics exporter must never break the pool.
Rng
A source of uniform f64s in [0, 1). Mirrors random.Random.random() / rand.Rand.Float64() from the sibling implementations.

Type Aliases§

FactoryError
The boxed error type a ConnectionFactory returns from create/reset/close. Any std::error::Error works.