connpool/lib.rs
1//! `connpool` — a generic connection pool for Rust, dependency-free (blocking) with an
2//! optional async pool behind the `tokio` feature.
3//!
4//! It pools *anything* a small user-supplied [`ConnectionFactory`] can `create`, `validate`,
5//! `reset` and `close` — DB drivers, HTTP clients, SSH sessions, raw sockets. The pool knows
6//! nothing about your connection except what the factory tells it.
7//!
8//! # Layers (each only depends on the ones above it)
9//!
10//! ```text
11//! core errors, clocks, connection bookkeeping, timeout math
12//! resilience circuit breaker, retry/backoff
13//! policy PoolConfig + the pure retirement rules
14//! factories ConnectionFactory: the seam users implement to pool anything
15//! observability listeners + stats
16//! pools ConnectionPool, AsyncConnectionPool, PoolRegistry
17//! ```
18//!
19//! `connpool` is the Rust member of [poolyglot](https://github.com/Jeffeek/poolyglot): one
20//! pooling model implemented per language, kept API-parallel. Field names, event names,
21//! defaults, and [`CloseReason`]/[`BreakerState`] wire values are identical to the Python,
22//! C#, Java, Go and TypeScript implementations — switching languages is a syntax change, not
23//! a model change.
24//!
25//! # Example
26//!
27//! ```
28//! use connpool::{ConnectionPool, FnFactory, PoolConfig, Timeout};
29//! use std::sync::Arc;
30//! use std::sync::atomic::{AtomicU64, Ordering};
31//!
32//! // A toy "connection": a unique id behind an Arc so clones share identity.
33//! let next = Arc::new(AtomicU64::new(0));
34//! let factory = FnFactory::new({
35//! let next = next.clone();
36//! move || Ok::<_, connpool::FactoryError>(Arc::new(next.fetch_add(1, Ordering::SeqCst)))
37//! });
38//!
39//! let pool = ConnectionPool::new(factory, PoolConfig { max_size: 4, ..Default::default() }, None)
40//! .expect("valid config");
41//! let conn = pool.acquire(Timeout::Unset).expect("acquire");
42//! // ... use conn ...
43//! pool.release(conn).expect("release");
44//! ```
45//!
46//! Connections are tracked by value identity, so `T` must be `Clone + Eq + Hash` — use a
47//! cheap handle type such as `Arc<Conn>` or an id (the direct analog of the Go port's
48//! `comparable` constraint).
49
50// Layer modules (downward-only dependency direction).
51mod core;
52mod factories;
53mod observability;
54mod policy;
55mod pools;
56mod resilience;
57mod rng;
58
59#[cfg(all(test, feature = "tokio"))]
60mod async_test_support;
61#[cfg(test)]
62mod test_support;
63
64// ---- public-API facade: one import surface re-exporting the whole library ----
65
66pub use crate::core::clock::{Clock, ManualClock, SystemClock};
67pub use crate::core::connection::{CloseReason, PooledConnection};
68pub use crate::core::errors::{FactoryError, PoolError};
69pub use crate::core::timeouts::Timeout;
70
71pub use crate::resilience::breaker::{BreakerConfig, BreakerState, CircuitBreaker};
72pub use crate::resilience::retry::RetryPolicy;
73
74pub use crate::policy::config::{IdleStrategy, PoolConfig};
75
76pub use crate::factories::sync_factory::{ConnectionFactory, FnFactory};
77
78pub use crate::observability::events::PoolListener;
79pub use crate::observability::stats::{PoolStats, StatValue};
80
81pub use crate::pools::registry::PoolRegistry;
82pub use crate::pools::sync_pool::{ConnectionPool, PoolOptions};
83
84pub use crate::rng::{Rng, SystemRng};
85
86#[cfg(feature = "tokio")]
87pub use crate::factories::async_factory::{AsyncConnectionFactory, AsyncFnFactory};
88#[cfg(feature = "tokio")]
89pub use crate::pools::async_pool::AsyncConnectionPool;
90#[cfg(feature = "tokio")]
91pub use crate::pools::async_registry::AsyncPoolRegistry;
92
93/// The released version of this crate, kept in lock-step with the root `VERSION` file.
94pub const VERSION: &str = env!("CARGO_PKG_VERSION");