3个不稳定版本
0.2.1 | 2024年6月24日 |
---|---|
0.2.0 | 2024年6月24日 |
0.1.0 | 2024年6月18日 |
#384 in 异步
20KB
367 行
异步延迟调用
此crate实现了主动对象设计模式。
此crate的入口点是Dispatcher
,它封装了一个Arc<Lock<T>>
。
注意:锁可以是来自async-lock
crate 的 RwLock
或 Mutex
。
Dispatcher
Dispatcher
允许您为 T
上的某些方法创建 Caller
。
然后您可以通过这些 Caller
调度对这些方法的延迟调用。
Dispatcher
实现了 Future
;您必须等待这个future,才能实际分发调用。
Caller
当您使用 Dispatcher
为 T
的一个方法创建 Caller
时,会创建一个后台任务,等待您通过 Caller
调度延迟调用。当调用被调度时,后台任务将锁定 RwLock
或 Mutex
并在锁定状态下调用 T
实例上的方法。
兼容的 T
方法
方法必须
- 是异步的
- 返回一个实现
ReturnType
的类型
它们可以以可变或不可变方式接受 self
。
注意:如果函数的第一个参数是 &T
或 &mut T
,则可以使用独立的函数代替方法。
召唤者
如果方法的最后一个参数是async_channel::Sender
,您可以将您的Caller
转换为Summoner
,这使得在安排调用时等待回复变得容易。
示例
use async_defer::{*, async_channel::Sender, async_lock::RwLock};
use std::time::{Instant, Duration};
use std::sync::Arc;
// An example object which will be modified in deferred calls
struct Subject;
impl Subject {
async fn print(&mut self, msg: String) -> Result<(), String> {
println!("msg: {}", msg);
Ok(())
}
async fn ping_pong(&self, payload: u8, reply: Sender<u8>) -> Result<(), String> {
let _ = reply.send(payload).await;
Ok(())
}
}
let world = Arc::new(RwLock::new(Subject));
let mut dispatcher = Dispatcher::new(world);
let deferred_print = dispatcher.listen_mut_1(Subject::print);
let deferred_ping_pong = dispatcher.listen_ref_2(Subject::ping_pong);
async {
deferred_print.call("Hello World".to_string()).await;
let later = Instant::now() + Duration::from_secs(5);
deferred_print.call_later(later, "Hello World".to_string()).await;
// `ping_pong` has a reply parameter,
// allowing us to create a `Summoner`.
let summoner = deferred_ping_pong.summoner();
let rep = summoner.summon(5).await;
println!("reply: {}", rep);
};
在这个示例中,创建了两个后台任务,每个任务对应于Subject
的一个方法。`ping_pong`方法的最后一个参数是Sender,允许我们“召唤”该方法。
依赖项
~3–11MB
~135K SLoC