#connection-pool #async-pool #postgresql #pool #async #connection-manager

deadpool-postgres

为 tokio-postgres 提供简单易用的异步连接池

33 个版本 (12 个破坏性更新)

0.14.0 2024年6月4日
0.13.0 2024年3月31日
0.12.1 2023年12月18日
0.11.0 2023年9月26日
0.2.1 2019年11月18日

#219 in 数据库接口

Download history 29540/week @ 2024-05-03 41487/week @ 2024-05-10 49284/week @ 2024-05-17 42322/week @ 2024-05-24 35980/week @ 2024-05-31 51143/week @ 2024-06-07 41798/week @ 2024-06-14 41023/week @ 2024-06-21 43772/week @ 2024-06-28 39609/week @ 2024-07-05 43973/week @ 2024-07-12 40888/week @ 2024-07-19 38401/week @ 2024-07-26 45443/week @ 2024-08-02 53552/week @ 2024-08-09 46153/week @ 2024-08-16

191,810 每月下载量
用于 59 个 Crates (46 个直接使用)

MIT/Apache

130KB
2.5K SLoC

Deadpool 是一个用于任何类型连接和对象的简单异步连接池。最新版本 禁止不安全 Rust 1.75+

Deadpool 是一个用于连接和任何类型对象的简单异步连接池。

此 crate 实现了一个 deadpool 管理器,用于 tokio-postgres,并提供了通过包装 tokio_postgres::Clienttokio_postgres::Transaction 的方式实现的 statement 缓存。

特性

特性 描述 额外依赖 默认
rt_tokio_1 启用对 tokio crate 的支持 deadpool/rt_tokio_1
rt_async-std_1 启用对 async-std crate 的支持 deadpool/rt_async-std_1
serde 启用对 serde crate 的支持 deadpool/serde, serde/derive

重要: async-std 支持目前仅限于 async-std 特定的超时函数。您仍然需要启用 async-std 中的 tokio1 特性,才能使用此 crate 与 async-std 一起使用。

示例

以下示例假设通过Unix域套接字可访问PostgreSQL,并且已为本地用户在pg_hba.conf中启用了对等认证。如果您正在运行Windows,您可能需要在连接配置中指定hostuserpassword,或者使用其他认证方法

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);
    }
}

使用configdotenvy 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);
    }
}

注意: 上面的代码使用crate名称config_crate,因为存在config功能,并且功能和依赖项共享相同的命名空间。在您的代码中,您可能希望使用::config::ConfigError::config::Config

使用现有的tokio_postgres::Config对象的示例

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);
    }
}

常见问题解答

  • 数据库不可达。为什么池创建不会失败?

    Deadpool具有相同的启动和运行时行为,因此池创建永远不会失败。

    如果您希望在启动时如果无法建立数据库连接则使应用程序崩溃,请在创建池后立即调用pool.get().await

  • 为什么有时从池中检索的连接不可用?

    deadpool-postgres 0.5.5中,实现了一种新的回收方法,从0.8开始成为默认方法。使用此回收方法,管理器在返回连接之前不再执行测试查询,而是完全依赖tokio_postgres::Client::is_closed。在某些罕见情况下(例如,不可靠的网络),这可能导致tokio_postgres没有注意到断开连接并报告连接为可用。

    可以通过将ManagerConfig::recycling_method设置为RecyclingMethod::Verified或在使用config crate时设置PG__MANAGER__RECYCLING_METHOD=Verified来启用旧的、稍微慢一些的回收方法。

  • 如何启用tokio-postgres crate的功能?

    请确保您依赖于与deadpool-postgres相同的tokio-postgres版本,并在您的自己的Crate.toml文件中启用所需的特性

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

    重要: deadpool-postgrestokio-postgres的版本号不一定匹配。如果它们匹配,这只是两个crate具有相同的MAJOR和MINOR版本号的巧合。

    deadpool-postgres tokio-postgres
    0.7 – 0.12 0.7
    0.6 0.6
    0.4 – 0.5 0.5
    0.2 – 0.3 0.5.0-alpha
  • 如何清除语句缓存?

    您可以通过调用 pool.manager().statement_cache.clear() 来清除所有语句缓存,或者通过调用 pool.manager().statement_cache.remove() 来从所有缓存中移除单个语句。

    重要: ClientWrapper 还提供了一个 statement_cache 字段,该字段具有 clear()remove() 方法,这些方法仅影响单个客户端。

许可

根据您选择的以下任何一项进行许可:

任选其一。

依赖

~3–14MB
~181K SLoC