pub struct Pool<M: Manager>(/* private fields */);std only.Expand description
A thread-safe pool of reusable resources.
A Pool<M> lends out resources built by a Manager, reclaiming and
recycling each one when its Pooled guard is dropped. It is cheap to clone
— every clone is a handle onto the same shared pool — so share it across
threads by cloning rather than wrapping it in another Arc.
The pool is runtime-agnostic and carries no async dependency.
get blocks the calling thread until a resource is available; in
an async context, acquire on a blocking-friendly executor thread (for example
tokio::task::spawn_blocking). The returned guard is Send, so it can be
held across .await points.
§Examples
use pool_mod::{Manager, Pool};
use std::convert::Infallible;
struct Connections;
impl Manager for Connections {
type Resource = String;
type Error = Infallible;
fn create(&self) -> Result<String, Infallible> { Ok(String::new()) }
fn recycle(&self, c: &mut String) -> Result<(), Infallible> { c.clear(); Ok(()) }
}
let pool = Pool::builder(Connections).max_size(4).build()
.expect("configuration is valid");
let mut conn = pool.get().expect("a connection is available");
conn.push_str("SELECT 1");
assert_eq!(pool.status().in_use, 1);
drop(conn);
assert_eq!(pool.status().in_use, 0);Implementations§
Source§impl<M: Manager> Pool<M>
impl<M: Manager> Pool<M>
Sourcepub fn builder(manager: M) -> Builder<M>
pub fn builder(manager: M) -> Builder<M>
Start building a pool for manager with the default configuration.
§Examples
use pool_mod::{Manager, Pool};
use std::convert::Infallible;
let pool = Pool::builder(M).max_size(8).min_idle(2).build()
.expect("configuration is valid");
assert_eq!(pool.status().max_size, 8);Sourcepub fn new(manager: M) -> Result<Self, Error<M::Error>>
pub fn new(manager: M) -> Result<Self, Error<M::Error>>
Build a pool for manager with the default configuration.
A shortcut for Pool::builder(manager).build().
§Errors
Returns Error::Backend if pre-creating the initial resources fails.
(With the default min_idle of 0, no resources are created up front, so
the default-configured pool only fails to build if you have customized the
configuration through Pool::builder instead.)
§Examples
use pool_mod::{Manager, Pool};
use std::convert::Infallible;
let pool = Pool::new(M).expect("configuration is valid");
assert_eq!(pool.status().max_size, 10); // the defaultSourcepub fn get(&self) -> Result<Pooled<M>, Error<M::Error>>
pub fn get(&self) -> Result<Pooled<M>, Error<M::Error>>
Borrow a resource, waiting up to the configured
create_timeout if the pool is saturated.
Reuses an idle resource when one is available (after validation), grows the
pool toward max_size when it is not, and otherwise blocks until a
resource is returned or the timeout elapses.
§Errors
Error::Backendif the manager fails to create a resource.Error::Timeoutif the pool stays saturated pastcreate_timeout.Error::Closedif the pool has been closed.
§Examples
use pool_mod::{Manager, Pool};
use std::convert::Infallible;
let pool = Pool::builder(M).max_size(2).build().expect("valid");
let resource = pool.get().expect("available");
assert_eq!(*resource, 7);Sourcepub fn get_timeout(
&self,
timeout: Duration,
) -> Result<Pooled<M>, Error<M::Error>>
pub fn get_timeout( &self, timeout: Duration, ) -> Result<Pooled<M>, Error<M::Error>>
Borrow a resource, waiting at most timeout regardless of the configured
create_timeout.
A timeout of Duration::ZERO makes this a non-blocking try: it returns
Error::Timeout at once if no resource can be handed out immediately.
§Errors
Error::Backendif the manager fails to create a resource.Error::Timeoutif no resource becomes available withintimeout.Error::Closedif the pool has been closed.
§Examples
use std::time::Duration;
use pool_mod::{Error, Manager, Pool};
use std::convert::Infallible;
let pool = Pool::builder(M).max_size(1).build().expect("valid");
let held = pool.get().expect("first checkout");
// The single slot is taken, so an immediate retry times out.
assert!(matches!(pool.get_timeout(Duration::ZERO), Err(Error::Timeout)));Sourcepub fn try_get(&self) -> Result<Pooled<M>, Error<M::Error>>
pub fn try_get(&self) -> Result<Pooled<M>, Error<M::Error>>
Borrow a resource without ever blocking.
Returns a resource if one can be handed out immediately — an idle resource
is ready, or the pool has room to create one — and otherwise returns
Error::Timeout at once. Equivalent to
get_timeout(Duration::ZERO).
§Errors
Error::Backendif the manager fails to create a resource.Error::Timeoutif no resource is immediately available.Error::Closedif the pool has been closed.
§Examples
use pool_mod::{Error, Manager, Pool};
use std::convert::Infallible;
let pool = Pool::builder(M).max_size(1).build().expect("valid");
let first = pool.try_get().expect("room to create one");
// The only slot is taken, so the next try fails immediately.
assert!(matches!(pool.try_get(), Err(Error::Timeout)));Sourcepub fn status(&self) -> Status
pub fn status(&self) -> Status
Take a snapshot of the pool’s current occupancy.
§Examples
use pool_mod::{Manager, Pool};
use std::convert::Infallible;
let pool = Pool::builder(M).max_size(4).min_idle(1).build().expect("valid");
let status = pool.status();
assert_eq!(status.idle, 1);
assert_eq!(status.max_size, 4);Sourcepub fn close(&self)
pub fn close(&self)
Close the pool: discard every idle resource and reject all future
checkouts with Error::Closed.
Resources currently checked out are unaffected and are simply dropped (not returned to the idle set) when their guards fall. Closing is idempotent. Idle resources are dropped outside the pool’s lock, so a slow resource destructor does not block other threads.
§Examples
use pool_mod::{Error, Manager, Pool};
use std::convert::Infallible;
let pool = Pool::builder(M).max_size(2).min_idle(2).build().expect("valid");
pool.close();
assert!(pool.is_closed());
assert!(matches!(pool.get(), Err(Error::Closed)));