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 数据库接口
191,810 每月下载量
用于 59 个 Crates (46 个直接使用)
130KB
2.5K SLoC
Deadpool 是一个用于任何类型连接和对象的简单异步连接池。
Deadpool 是一个用于连接和任何类型对象的简单异步连接池。
此 crate 实现了一个 deadpool
管理器,用于 tokio-postgres
,并提供了通过包装 tokio_postgres::Client
和 tokio_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,您可能需要在连接配置中指定host
、user
和password
,或者使用其他认证方法。
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);
}
}
使用config
和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);
}
}
注意: 上面的代码使用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-postgres
和tokio-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()
方法,这些方法仅影响单个客户端。
许可
根据您选择的以下任何一项进行许可:
- Apache License,版本 2.0 (LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
依赖
~3–14MB
~181K SLoC