3个不稳定版本
0.2.1 | 2024年5月15日 |
---|---|
0.2.0 | 2024年5月15日 |
0.1.0 | 2023年10月17日 |
#981 in 数据库接口
每月259次下载
在 qorb 中使用
37KB
518 行
async-bb8-diesel
此crate提供了一种异步访问bb8连接池的接口,该接口建立在Diesel之上。
这是通过实现Diesel的"RunQueryDsl"特质的异步版本,命名为"AsyncRunQueryDsl",在异步兼容的连接上操作来实现的。当从异步上下文调用时,这些操作将查询转移到阻塞的tokio线程中,在那里可以执行。
注意:此crate早于diesel-async。对于新代码,请考虑直接使用该接口。
先决条件
- 愿意容忍一些不稳定性。此crate实际上起源于一个临时的解决方案,直到Diesel内部存在更多本机异步支持。
与现有crate的比较
此crate深受tokio-diesel和bb8-diesel的启发,但服务于稍微不同的目的。
那些crate做什么?
这两个crate都严重依赖tokio::block_in_place
函数来实际执行同步Diesel查询。
它们的流程实际上是
- 发出一个查询(在tokio-diesel的情况下是异步的。在bb8-diesel的情况下是同步的——但你正在使用bb8,所以假设你是从异步任务中调用的)。
- 将查询和数据库连接移动到
block_in_place
调用中。 - 在
block_in_place
中使用Diesel的本地同步API。
采用这种方法的这些crate有一些优点
- tokio执行器知道在
block_in_place
调用期间不要调度额外的异步任务。 - 在
block_in_place
中使用的回调不需要是Send
- 它在异步任务的其他部分同步执行。
然而,它们也有一些缺点
block_in_place
的调用实际上暂停了异步线程的调用期间。这需要一个多线程的运行时环境,并在调用期间降低了其中一个线程的有效性。block_in_place
的调用会饿死同一任务中运行的所有其他异步代码。
这种饥饿导致对其他未来的某些微妙抑制,例如以下示例中,如果从同一任务发出超时操作,则将忽略超时。
tokio::select! {
// Calls "tokio::block_in_place", doing a synchronous Diesel operation
// on the calling thread...
_ = perform_database_operation() => {},
// ... meaning this asynchronous timeout cannot complete!
_ = sleep_until(timeout) = {},
}
这个crate有什么作用?
这个crate试图避免调用block_in_place
(这会阻塞调用线程),并更愿意使用tokio::spawn_blocking
函数。这个函数将请求的操作移动到一个完全不同的线程,在那里阻塞是可以接受的,但不会阻止当前任务执行其他异步工作。
这并不是完全免费的——因为这项工作现在需要转移到新的线程,它对构造查询施加了“Send + 'static”约束。
哪个适合我?
- 如果你关心保留通常期望的异步操作语义,我们建议使用这个crate。
- 如果你不关心——也许你有一个异步工作负载,但你知道何时可以阻塞这些线程——你可以使用tokio-diesel或bb8-diesel crate,具体取决于你是否需要访问异步线程池。
依赖项
~6–13MB
~139K SLoC