Skip to content

Commit 0ed6e2c

Browse files
author
Ariel Ben-Yehuda
committed
make self-tracing public
1 parent 3b677d1 commit 0ed6e2c

File tree

3 files changed

+113
-2
lines changed

3 files changed

+113
-2
lines changed

tokio/src/runtime/dump.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@
33
//! See [Handle::dump][crate::runtime::Handle::dump].
44
55
use crate::task::Id;
6-
use std::fmt;
6+
use std::{fmt, future::Future};
7+
8+
pub use crate::runtime::task::trace::Root;
9+
10+
/// missing dok
11+
pub fn root<F: Future>(f: F) -> Root<F> {
12+
crate::runtime::task::trace::Trace::root(f)
13+
}
714

815
/// A snapshot of a runtime's state.
916
///
@@ -38,6 +45,25 @@ pub struct Trace {
3845
inner: super::task::trace::Trace,
3946
}
4047

48+
impl Trace {
49+
/// document
50+
pub fn capture<F, R>(f: F) -> (R, Trace)
51+
where
52+
F: FnOnce() -> R,
53+
{
54+
let (res, trace) = super::task::trace::Trace::capture(f);
55+
(res, Trace { inner: trace })
56+
}
57+
58+
/// doc doc doc
59+
pub fn root<F>(f: F) -> Root<F>
60+
where
61+
F: Future,
62+
{
63+
crate::runtime::task::trace::Trace::root(f)
64+
}
65+
}
66+
4167
impl Dump {
4268
pub(crate) fn new(tasks: Vec<Task>) -> Self {
4369
Self {

tokio/src/runtime/task/trace/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ pub(crate) struct Trace {
5656
pin_project_lite::pin_project! {
5757
#[derive(Debug, Clone)]
5858
#[must_use = "futures do nothing unless you `.await` or poll them"]
59-
pub(crate) struct Root<T> {
59+
/// Dok: roots a trace
60+
pub struct Root<T> {
6061
#[pin]
6162
future: T,
6263
}

tokio/tests/task_trace_self.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#![cfg(all(tokio_unstable, tokio_taskdump, feature = "full", not(target_os = "wasi"), not(miri)))] // Wasi doesn't support bind
2+
3+
use std::{
4+
future::Future,
5+
mem,
6+
pin::Pin,
7+
sync::{Arc, Mutex},
8+
task::{Context, Poll},
9+
time::{Duration, Instant},
10+
};
11+
12+
use tokio::runtime::dump::{Root, Trace};
13+
14+
pin_project_lite::pin_project! { pub struct PrettyFuture<F: Future> {
15+
#[pin]
16+
f: Root<F>,
17+
t_last: Option<Instant>,
18+
logs: Arc<Mutex<Vec<Trace>>>,
19+
}
20+
}
21+
22+
impl<F: Future> PrettyFuture<F> {
23+
pub fn pretty(f: F, logs: Arc<Mutex<Vec<Trace>>>) -> Self {
24+
PrettyFuture {
25+
f: Trace::root(f),
26+
t_last: None,
27+
logs,
28+
}
29+
}
30+
}
31+
32+
impl<F: Future> Future for PrettyFuture<F> {
33+
type Output = F::Output;
34+
35+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<F::Output> {
36+
let mut this = self.project();
37+
let now = Instant::now();
38+
let t_last = mem::replace(this.t_last, Some(now));
39+
if t_last.is_some_and(|t_last| now.duration_since(t_last) > Duration::from_millis(10)) {
40+
let (res, trace) = tokio::runtime::dump::Trace::capture(|| this.f.as_mut().poll(cx));
41+
this.logs.lock().unwrap().push(trace);
42+
return res;
43+
}
44+
this.f.as_mut().poll(cx)
45+
}
46+
}
47+
48+
#[tokio::test]
49+
async fn task_trace_self() {
50+
let log = Arc::new(Mutex::new(vec![]));
51+
let log2 = Arc::new(Mutex::new(vec![]));
52+
let mut good_line = vec![];
53+
let mut bad_line = vec![];
54+
PrettyFuture::pretty(
55+
PrettyFuture::pretty(
56+
async {
57+
bad_line.push(line!() + 1);
58+
tokio::task::yield_now().await;
59+
bad_line.push(line!() + 1);
60+
tokio::time::sleep(Duration::from_millis(1)).await;
61+
good_line.push(line!() + 1);
62+
tokio::time::sleep(Duration::from_millis(1000)).await;
63+
},
64+
log.clone(),
65+
),
66+
log2.clone(),
67+
)
68+
.await;
69+
for line in good_line {
70+
let s = format!("{}:{}:", file!(), line);
71+
assert!(log.lock().unwrap().iter().any(|x| {
72+
eprintln!("{}", x);
73+
format!("{}", x).contains(&s)
74+
}));
75+
}
76+
for line in bad_line {
77+
let s = format!("{}:{}:", file!(), line);
78+
assert!(!log
79+
.lock()
80+
.unwrap()
81+
.iter()
82+
.any(|x| format!("{}", x).contains(&s)));
83+
}
84+
}

0 commit comments

Comments
 (0)