Crate deadpool_postgres

Source
Expand description

§Deadpool for PostgreSQL Latest Version Unsafe forbidden Rust 1.75+

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

This crate implements a deadpool manager for tokio-postgres and also provides a statement cache by wrapping tokio_postgres::Client and tokio_postgres::Transaction.

§Features

FeatureDescriptionExtra dependenciesDefault
rt_tokio_1Enable support for tokio cratedeadpool/rt_tokio_1yes
rt_async-std_1Enable support for async-std cratedeadpool/rt_async-std_1no
serdeEnable support for serde cratedeadpool/serde, serde/deriveno

Important: async-std support is currently limited to the async-std specific timeout function. You still need to enable the tokio1 feature of async-std in order to use this crate with async-std.

§Example

The following example assumes a PostgreSQL reachable via an unix domain socket and peer auth enabled for the local user in pg_hba.conf. If you’re running Windows you probably want to specify the host, user and password in the connection config or use an alternative authentication method.

use deadpool_postgres::{Config, ManagerConfig, RecyclingMethod, Runtime};
use tokio_postgres::NoTls;

#[tokio::main]
async fn main() {
    let mut cfg = Config::new();
    cfg.dbname = Some("deadpool".to_string());
    cfg.manager = Some(ManagerConfig {
        recycling_method: RecyclingMethod::Fast,
    });
    let pool = cfg.create_pool(Some(Runtime::Tokio1), NoTls).unwrap();
    for i in 1..10i32 {
        let client = pool.get().await.unwrap();
        let stmt = client.prepare_cached("SELECT 1 + $1").await.unwrap();
        let rows = client.query(&stmt, &[&i]).await.unwrap();
        let value: i32 = rows[0].get(0);
        assert_eq!(value, i + 1);
    }
}

§Example with config and dotenvy crate

# .env
PG__DBNAME=deadpool
use deadpool_postgres::Runtime;
use dotenvy::dotenv;
use tokio_postgres::NoTls;

#[derive(Debug, serde::Deserialize)]
struct Config {
    pg: deadpool_postgres::Config,
}

impl Config {
    pub fn from_env() -> Result<Self, config::ConfigError> {
        config::Config::builder()
            .add_source(config::Environment::default().separator("__"))
            .build()?
            .try_deserialize()
    }
}

#[tokio::main]
async fn main() {
    dotenv().ok();
    let cfg = Config::from_env().unwrap();
    let pool = cfg.pg.create_pool(Some(Runtime::Tokio1), NoTls).unwrap();
    for i in 1..10i32 {
        let client = pool.get().await.unwrap();
        let stmt = client.prepare_cached("SELECT 1 + $1").await.unwrap();
        let rows = client.query(&stmt, &[&i]).await.unwrap();
        let value: i32 = rows[0].get(0);
        assert_eq!(value, i + 1);
    }
}

Note: The code above uses the crate name config_crate because of the config feature and both features and dependencies share the same namespace. In your own code you will probably want to use ::config::ConfigError and ::config::Config instead.

§Example using an existing tokio_postgres::Config object

use deadpool_postgres::{Manager, ManagerConfig, Pool, RecyclingMethod};
use std::env;
use tokio_postgres::NoTls;

#[tokio::main]
async fn main() {
    let mut pg_config = tokio_postgres::Config::new();
    pg_config.host_path("/run/postgresql");
    pg_config.host_path("/tmp");
    pg_config.user(env::var("USER").unwrap().as_str());
    pg_config.dbname("deadpool");
    let mgr_config = ManagerConfig {
        recycling_method: RecyclingMethod::Fast,
    };
    let mgr = Manager::from_config(pg_config, NoTls, mgr_config);
    let pool = Pool::builder(mgr).max_size(16).build().unwrap();
    for i in 1..10i32 {
        let client = pool.get().await.unwrap();
        let stmt = client.prepare_cached("SELECT 1 + $1").await.unwrap();
        let rows = client.query(&stmt, &[&i]).await.unwrap();
        let value: i32 = rows[0].get(0);
        assert_eq!(value, i + 1);
    }
}

§FAQ

  • The database is unreachable. Why does the pool creation not fail?

    Deadpool has identical startup and runtime behaviour and therefore the pool creation will never fail.

    If you want your application to crash on startup if no database connection can be established just call pool.get().await right after creating the pool.

  • Why are connections retrieved from the pool sometimes unuseable?

    In deadpool-postgres 0.5.5 a new recycling method was implemented which is the default since 0.8. With that recycling method the manager no longer performs a test query prior returning the connection but relies solely on tokio_postgres::Client::is_closed instead. Under some rare circumstances (e.g. unreliable networks) this can lead to tokio_postgres not noticing a disconnect and reporting the connection as useable.

    The old and slightly slower recycling method can be enabled by setting ManagerConfig::recycling_method to RecyclingMethod::Verified or when using the config crate by setting PG__MANAGER__RECYCLING_METHOD=Verified.

  • How can I enable features of the tokio-postgres crate?

    Make sure that you depend on the same version of tokio-postgres as deadpool-postgres does and enable the needed features in your own Crate.toml file:

    [dependencies]
    deadpool-postgres = { version = "0.9" }
    tokio-postgres = { version = "0.7", features = ["with-uuid-0_8"] }

    Important: The version numbers of deadpool-postgres and tokio-postgres do not necessarily match. If they do it is just a coincidence that both crates have the same MAJOR and MINOR version number.

    deadpool-postgrestokio-postgres
    0.7 – 0.120.7
    0.60.6
    0.4 – 0.50.5
    0.2 – 0.30.5.0-alpha
  • How can I clear the statement cache?

    You can call pool.manager().statement_cache.clear() to clear all statement caches or pool.manager().statement_cache.remove() to remove a single statement from all caches.

    Important: The ClientWrapper also provides a statement_cache field which has clear() and remove() methods which only affect a single client.

§License

Licensed under either of

at your option.

Re-exports§

pub use tokio_postgres;

Structs§

ClientWrapper
Wrapper around tokio_postgres::Client with a StatementCache.
Config
Configuration object.
ConfigConnectImpl
Provides an implementation of Connect that establishes the connection using the tokio_postgres configuration itself.
Manager
Manager for creating and recycling PostgreSQL connections.
ManagerConfig
Configuration object for a Manager.
Metrics
Statistics regarding an object returned by the pool
PoolConfig
Pool configuration.
StatementCache
Representation of a cache of Statements.
StatementCaches
Structure holding a reference to all StatementCaches and providing access for clearing all caches and removing single statements from them.
Status
The current pool status.
Timeouts
Timeouts when getting Objects from a Pool.
Transaction
Wrapper around tokio_postgres::Transaction with a StatementCache from the Client object it was created by.
TransactionBuilder
Wrapper around tokio_postgres::TransactionBuilder with a StatementCache from the Client object it was created by.

Enums§

ChannelBinding
Channel binding configuration.
ConfigError
This error is returned if there is something wrong with the configuration
LoadBalanceHosts
Load balancing configuration.
RecyclingMethod
Possible methods of how a connection is recycled.
Runtime
Enumeration for picking a runtime implementation.
SslMode
TLS configuration.
TargetSessionAttrs
Properties required of a session.

Traits§

Connect
Describes a mechanism for establishing a connection to a PostgreSQL server via tokio_postgres.
GenericClient
A trait allowing abstraction over connections and transactions.

Type Aliases§

BuildError
Type alias for using deadpool::managed::BuildError with tokio_postgres.
Client
Type alias for Object
CreatePoolError
Type alias for using deadpool::managed::CreatePoolError with tokio_postgres.
Hook
Type alias for using deadpool::managed::Hook with tokio_postgres.
HookError
Type alias for using deadpool::managed::HookError with tokio_postgres.
Object
Type alias for using deadpool::managed::Object with tokio_postgres.
Pool
Type alias for using deadpool::managed::Pool with tokio_postgres.
PoolBuilder
Type alias for using deadpool::managed::PoolBuilder with tokio_postgres.
PoolError
Type alias for using deadpool::managed::PoolError with tokio_postgres.