Home

Awesome

Deadpool Latest Version Build Status Unsafe forbidden Rust 1.75+

Deadpool is a dead simple async pool for connections and objects of any type.

This crate provides two implementations:

Features

FeatureDescriptionExtra dependenciesDefault
managedEnable managed pool implementation-yes
unmanagedEnable unmanaged pool implementation-yes
rt_tokio_1Enable support for tokio cratetokio/timeno
rt_async-std_1Enable support for async-std crateasync-stdno
serdeEnable support for deserializing pool configserde/deriveno

The runtime features (rt_*) are only needed if you need support for timeouts. If you try to use timeouts without specifying a runtime at pool creation the pool get methods will return an PoolError::NoRuntimeSpecified error.

Managed pool (aka. connection pool)

This is the obvious choice for connection pools of any kind. Deadpool already comes with a couple of database connection pools which work out of the box.

Example

use deadpool::managed;

#[derive(Debug)]
enum Error { Fail }

struct Computer {}

impl Computer {
    async fn get_answer(&self) -> i32 {
        42
    }
}

struct Manager {}

impl managed::Manager for Manager {
    type Type = Computer;
    type Error = Error;
    
    async fn create(&self) -> Result<Computer, Error> {
        Ok(Computer {})
    }
    
    async fn recycle(&self, _: &mut Computer, _: &managed::Metrics) -> managed::RecycleResult<Error> {
        Ok(())
    }
}

type Pool = managed::Pool<Manager>;

#[tokio::main]
async fn main() {
    let mgr = Manager {};
    let pool = Pool::builder(mgr).build().unwrap();
    let mut conn = pool.get().await.unwrap();
    let answer = conn.get_answer().await;
    assert_eq!(answer, 42);
}

Database connection pools

Deadpool supports various database backends by implementing the deadpool::managed::Manager trait. The following backends are currently supported:

BackendCrateLatest Version
bolt-clientdeadpool-boltLatest Version
tokio-postgresdeadpool-postgresLatest Version
lapin (AMQP)deadpool-lapinLatest Version
redisdeadpool-redisLatest Version
async-memcacheddeadpool-memcachedLatest Version
rusqlitedeadpool-sqliteLatest Version
dieseldeadpool-dieselLatest Version
tiberiusdeadpool-tiberiusLatest Version
r2d2deadpool-r2d2Latest Version
rbatisrbatisLatest Version

Reasons for yet another connection pool

Deadpool is by no means the only pool implementation available. It does things a little different and that is the main reason for it to exist:

Unmanaged pool

An unmanaged pool is useful when you can't write a manager for the objects you want to pool or simply don't want to. This pool implementation is slightly faster than the managed pool because it does not use a Manager trait to create and recycle objects but leaves it up to the user.

Unmanaged pool example

use deadpool::unmanaged::Pool;

struct Computer {}

impl Computer {
    async fn get_answer(&self) -> i32 {
        42
    }
}

#[tokio::main]
async fn main() {
    let pool = Pool::from(vec![
        Computer {},
        Computer {},
    ]);
    let s = pool.get().await.unwrap();
    assert_eq!(s.get_answer().await, 42);
}

FAQ

Why does deadpool depend on tokio? I thought it was runtime agnostic...

Deadpool depends on tokio::sync::Semaphore. This does not mean that the tokio runtime or anything else of tokio is being used or will be part of your build. You can easily check this by running the following command in your own code base:

cargo tree --format "{p} {f}"

License

Licensed under either of

at your option.