29 个发布版本

0.12.1 2024 年 5 月 7 日
0.11.2 2024 年 4 月 10 日
0.11.0 2024 年 3 月 31 日
0.10.0 2023 年 9 月 25 日
0.2.0 2019 年 11 月 14 日

#6 in 数据库接口

Download history 195200/week @ 2024-05-02 204141/week @ 2024-05-09 221974/week @ 2024-05-16 217803/week @ 2024-05-23 221839/week @ 2024-05-30 237412/week @ 2024-06-06 221826/week @ 2024-06-13 221744/week @ 2024-06-20 248034/week @ 2024-06-27 215296/week @ 2024-07-04 228937/week @ 2024-07-11 236953/week @ 2024-07-18 243071/week @ 2024-07-25 239671/week @ 2024-08-01 267347/week @ 2024-08-08 271958/week @ 2024-08-15

1,068,152 每月下载次数
用于 494 个 Crates (75 直接)

MIT/Apache

80KB
1.5K SLoC

Deadpool 最新版本 构建状态 禁止不安全 Rust 1.75+

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

此 crate 提供了两种实现

  • 管理池 (deadpool::managed::Pool)

    • 按需创建和回收对象
    • 适用于 数据库连接池
    • 通过您的 Cargo.toml 中的 managed 功能启用
  • 未管理池 (deadpool::unmanaged::Pool)

    • 所有对象都需要由用户创建并手动添加到池中。也可以从现有对象集合创建池。
    • 通过您的 Cargo.toml 中的 unmanaged 功能启用

功能

功能 描述 额外依赖 默认
managed 启用管理池实现 -
unmanaged 启用未管理池实现 -
rt_tokio_1 启用对 tokio crate 的支持 tokio/时间
rt_async-std_1 启用对 async-std crate 的支持 async-std
序列化 启用对池配置反序列化的支持 序列化/derive

运行时功能(rt_*)仅在需要超时支持时才需要。如果在创建池时没有指定运行时,尝试使用超时,池的获取方法将返回一个 PoolError::NoRuntimeSpecified 错误。

托管池(又称连接池)

这是任何类型连接池的明显选择。Deadpool 已经内置了一些 数据库连接池,可以直接使用。

示例

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

数据库连接池

Deadpool 通过实现 deadpool::managed::Manager 特性来支持各种数据库后端。以下后端目前受支持

后端 Crate 最新版本
bolt-client deadpool-bolt Latest Version
tokio-postgres deadpool-postgres Latest Version
lapin (AMQP) deadpool-lapin Latest Version
redis deadpool-redis Latest Version
async-memcached deadpool-memcached Latest Version
rusqlite deadpool-sqlite Latest Version
diesel deadpool-diesel Latest Version
tiberius deadpool-tiberius Latest Version
r2d2 deadpool-r2d2 Latest Version
rbatis rbatis Latest Version

再次使用连接池的原因

Deadpool 绝非唯一可用的池实现。它做得略有不同,这就是它存在的主要原因。

  • Deadpool 与任何执行器兼容。 使用 Drop 特性将对象返回到池中。这些对象的健康状态在下次检索时检查,而不是在它们返回时检查。Deadpool 从不执行任何后台操作。这就是为什么 Deadpool 不需要生成 futures,也不依赖于任何类型的后台线程或任务。

  • 相同的启动和运行时行为。当编写长时间运行的应用程序时,如果数据库连接暂时不可用,通常在启动和运行时之间不应有任何差异。没有人会期望应用程序在运行时数据库不可用时崩溃。因此,在启动时也不应崩溃。创建池永远不会失败,错误仅在调用 Pool::get() 时返回。

    如果您真的想在启动时如果对象无法创建而导致应用程序崩溃,请直接在创建池后调用 pool.get().await.expect("DB connection failed")

  • Deadpool 很快。 在处理锁定原语时,它们被保持尽可能短的时间。当将对象返回到池中时,仅锁定一个互斥锁,当从池中检索对象时,使用信号量来尽可能减少互斥锁的竞争。

  • Deadpool 很简单。 简单到极点。API 表面很小。实际代码仅约 100 行代码,位于两个函数 Pool::getObject::drop 中。

  • Deadpool 可扩展。 通过使用 post_createpre_recyclepost_recycle 钩子,您可以自定义对象创建和回收以满足您的需求。

  • Deadpool 提供了见解。 所有对象都跟踪 Metrics,池提供了一个 status 方法,可用于了解其内部工作细节。

  • Deadpool 可调整大小。您可以在运行时调整池的大小,而无需重新启动应用程序。

非托管池

当您无法编写要池化的对象的经理,或者根本不想编写时,非托管池非常有用。此池实现比托管池稍快,因为它不使用 Manager 特性来 创建回收 对象,而是将其留给用户。

非托管池示例

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

常见问题解答

为什么 Deadpool 依赖于 tokio?我以为它是运行时无关的...

Deadpool 依赖于 tokio::sync::Semaphore。这 并不 意味着正在使用 tokio 运行时或其他 tokio 的一部分,或者它们将成为您的构建的一部分。您可以通过在自己的代码库中运行以下命令轻松检查此问题

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

许可证

根据您的选择,许可方式为:

依赖关系

~2–12MB
~138K SLoC