3 个版本
0.1.2 | 2021年7月19日 |
---|---|
0.1.1 | 2020年5月1日 |
0.1.0 | 2020年4月20日 |
在 异步 中排名第 83
每月下载量 53,611
在 87 个crate(直接使用 28 个)中使用
19KB
187 行
triggered
任务和线程之间的一次性事件触发器。
该机制由两种类型组成,即 Trigger
和 Listener
。它们作为一对出现。就像通道的发送者/接收者对一样。触发器部分有一个 Trigger::trigger
方法,将使所有等待监听器的任务/线程继续执行。监听器既有同步的 Listener::wait
方法,也实现了 Future<Output = ()>
以支持异步。
Trigger
和 Listener
都可以克隆。所以任何数量的触发器实例都可以触发任何数量的等待监听器。当任何一对触发器实例被触发时,所有等待的监听器都将被解除阻塞。等待已经触发的触发器的监听器将立即返回。因此,每个触发器/监听器对只能触发一次。
此crate不使用任何 unsafe
代码。
示例
一个简单的示例,展示基本用法
#[tokio::main]
async fn main() {
let (trigger, listener) = triggered::trigger();
let task = tokio::spawn(async {
// Blocks until `trigger.trigger()` below
listener.await;
println!("Triggered async task");
});
// This will make any thread blocked in `Listener::wait()` or async task awaiting the
// listener continue execution again.
trigger.trigger();
let _ = task.await;
}
一个示例,展示如何使用触发器/监听器对,在Ctrl-C事件上优雅地关闭一些异步服务器实例,其中只接受不可变的 Fn
闭包
#[tokio::main]
async fn main() -> Result<(), Error> {
let (shutdown_trigger, shutdown_signal1) = triggered::trigger();
// A sync `Fn` closure will trigger the trigger when the user hits Ctrl-C
ctrlc::set_handler(move || {
shutdown_trigger.trigger();
}).expect("Error setting Ctrl-C handler");
// If the server library has support for something like a shutdown signal:
let shutdown_signal2 = shutdown_signal1.clone();
let server1_task = tokio::spawn(async move {
SomeServer::new().serve_with_shutdown_signal(shutdown_signal1).await;
});
// Or just select between the long running future and the signal to abort it
tokio::select! {
server_result = SomeServer::new().serve() => {
eprintln!("Server error: {:?}", server_result);
}
_ = shutdown_signal2 => {}
}
let _ = server1_task.await;
Ok(())
}
Rust 兼容性
将至少与最新的两个稳定Rust版本兼容。这使用户在新稳定版发布后至少有六周的时间来升级他们的Rust工具链。
当前的MSRV可以在 travis.yml
中看到。任何对MSRV的更改都将被视为破坏性更改并列入 变更日志。
与类似原语的比较
通道
本库中的事件触发原语与通道有些相似。主要区别和开发此库的原因是
监听器与 futures::channel::oneshot::Receiver<()>
类似。但它
- 不可失败 - 实现了
Future<Output = ()>
而不是Future<Output = Result<T, Canceled>>
- 实现了
Clone
- 任意数量的监听器可以等待同一事件 - 有一个同步的
Listener::wait
- 同步线程和异步任务可以同时等待。
触发器与 futures::channel::oneshot::Sender<()>
相比有以下不同之处
- 不可失败 - 触发器不考虑是否有监听器剩下
- 发送时不会消耗自身,而是取
&self
- 因此可以在不是所有者或不可变的情况下使用。例如在Drop
实现或限于Fn
或FnMut
的回调闭包中。
futures::future::可取消
这些触发器的一个用例是在某些事件发生时取消future。请参见上面的示例。区别包括
- 单个句柄可以取消任何数量的future
- 有些future在仅通过
Abortable
丢弃时并没有得到适当的清理。这些库有时允许使用带有关闭信号的future来触发干净的取消。类似于serve_with_shutdown(signal: impl Future<Output = ()>)
。