Rust异步编程的可观察调试工具:Await-Tree
2024-02-05 17:21:08 软件 210观看
摘要Async Rust中的future可以任意组合或嵌套,以实现各种控制流。假设每个Future的执行都表示为一个节点,那么可以将异步任务的异步执行组织到一个逻辑树中,该逻辑树在Future的轮询、完成和取消过程中不断转换。在本文中,我们

Async Rust中的future可以任意组合或嵌套,以实现各种控制流。假设每个Future的执行都表示为一个节点,那么可以将异步任务的异步执行组织到一个逻辑树中,该逻辑树在Future的轮询、完成和取消过程中不断转换。oUk28资讯网——每日最新资讯28at.com

在本文中,我们将介绍Await-Tree,一个Async Rust的调试工具。它可以分析任务中的异步调用链和任务之间的依赖阻塞关系,以最小的运行时开销显著提高系统的可观察性和可调试性。await-tree允许开发人员在运行时转储这个执行树,每个Future的跨度由instrument_await注释。oUk28资讯网——每日最新资讯28at.com

下面我们看一个基本示例:oUk28资讯网——每日最新资讯28at.com

在Cargo.toml文件中,加入以下依赖项:oUk28资讯网——每日最新资讯28at.com

[dependencies]await-tree = "0.1.2"futures = "0.3.30"tokio = {version = "1.35.1", features = ["full"]}

oUk28资讯网——每日最新资讯28at.com

代码如下:oUk28资讯网——每日最新资讯28at.com

use std::time::Duration;use await_tree::{Config, InstrumentAwait, Registry};use futures::future::{join, pending};use tokio::time::sleep;async fn bar(i: i32) {    // `&'static str` span    baz(i).instrument_await("baz in bar").await}async fn baz(i: i32) {    // runtime `String` span is also supported    pending()        .instrument_await(format!("pending in baz {i}"))        .await}async fn foo() {    // spans of joined futures will be siblings in the tree    join(        bar(3).instrument_await("bar"),        baz(2).instrument_await("baz"),    )    .await;}#[tokio::main]async fn main() {    let mut registry = Registry::new(Config::default());    let root = registry.register((), "foo");    tokio::spawn(root.instrument(foo()));    sleep(Duration::from_secs(1)).await;    let tree = registry.get(&()).unwrap().to_string();    println!("{tree}");}

oUk28资讯网——每日最新资讯28at.com

执行cargo run,结果如下:oUk28资讯网——每日最新资讯28at.com

foo [1.002s]  baz [1.002s]    pending in baz 2 [1.002s]  bar [1.002s]    baz in bar [1.002s]      pending in baz 3 [1.002s]

oUk28资讯网——每日最新资讯28at.com

在代码中,我们有一些简单的async函数嵌套调用和使用join并发执行。与通常的代码不同,我们在希望跟踪的每个关键future后面添加.instrument_await,并为其指定名称。此名称可以是静态字符串常量,也可以包含其他运行时信息。oUk28资讯网——每日最新资讯28at.com

我们再看另外一个例子:oUk28资讯网——每日最新资讯28at.com

use std::time::Duration;use await_tree::{Config, InstrumentAwait, Registry};use futures::channel::oneshot::{self, Receiver};use futures::future::{pending, select};use futures::FutureExt;use tokio::time::sleep;async fn work(rx: Receiver<()>) {    let mut fut = pending().instrument_await("fut");    let _ = select(        sleep(Duration::from_millis(500))            .instrument_await("sleep")            .boxed(),        &mut fut,    )    .instrument_await("select")    .await;    // 等待信号继续    rx.instrument_await("rx").await.unwrap();    fut.await}#[tokio::main]async fn main() {    let mut registry = Registry::new(Config::default());    let root = registry.register((), "work");    let (tx, rx) = oneshot::channel();    tokio::spawn(root.instrument(work(rx)));    sleep(Duration::from_millis(100)).await;    let tree = registry.get(&()).unwrap().to_string();    println!("{tree}");    sleep(Duration::from_secs(1)).await;    let tree = registry.get(&()).unwrap().to_string();    println!("{tree}");    tx.send(()).unwrap();    sleep(Duration::from_secs(1)).await;    let tree = registry.get(&()).unwrap().to_string();    println!("{tree}");}

oUk28资讯网——每日最新资讯28at.com

结果如下:oUk28资讯网——每日最新资讯28at.com

work [101.181ms]  select [101.066ms]    fut [101.044ms]    sleep [101.044ms]work [1.103s]  rx [601.779ms][Detached 4]  fut [1.103s]work [2.105s]  fut [2.105s]

oUk28资讯网——每日最新资讯28at.com

这个例子展示了如何从树中分离并重新挂载一个span。oUk28资讯网——每日最新资讯28at.com

oUk28资讯网——每日最新资讯28at.com

oUk28资讯网——每日最新资讯28at.com

总结

在本文中,我们介绍了await- tree作为Async Rust中可观察性的强大工具。await- tree是为Async Rust原生设计的回溯工具,它允许开发者实时观察每个异步任务的执行状态,并分析不同future或任务之间的依赖阻塞关系。oUk28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-74193-0.htmlRust异步编程的可观察调试工具:Await-Tree

声明:本网页内容旨在传播知识,不代表本站观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。

显示全文

上一篇:.NET中使用BootstrapBlazor组件库Table实操篇

下一篇:创建线程的几种方式?你知道吗?

最新热点