3个不稳定版本

0.2.1 2024年6月24日
0.2.0 2024年6月24日
0.1.0 2024年6月18日

#384 in 异步

MIT 许可证

20KB
367

异步延迟调用

此crate实现了主动对象设计模式。

此crate的入口点是Dispatcher,它封装了一个Arc<Lock<T>>

注意:锁可以是来自async-lock crate 的 RwLockMutex

Dispatcher

Dispatcher 允许您为 T 上的某些方法创建 Caller

然后您可以通过这些 Caller 调度对这些方法的延迟调用。

Dispatcher 实现了 Future;您必须等待这个future,才能实际分发调用。

Caller

当您使用 DispatcherT 的一个方法创建 Caller 时,会创建一个后台任务,等待您通过 Caller 调度延迟调用。当调用被调度时,后台任务将锁定 RwLockMutex 并在锁定状态下调用 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