1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
use std::{
future::Future,
pin::Pin,
task::{Context, Poll},
};
use futures::{pin_mut, FutureExt};
use tracing::Instrument;
use tracing_subscriber::{layer::SubscriberExt, registry::Registry};
use tracing_tree::HierarchicalLayer;
fn main() {
let layer = HierarchicalLayer::default()
.with_writer(std::io::stdout)
.with_indent_lines(true)
.with_indent_amount(4)
.with_thread_names(true)
.with_thread_ids(true)
.with_span_retrace(true)
.with_deferred_spans(false)
.with_verbose_entry(true)
.with_targets(true);
let subscriber = Registry::default().with(layer);
tracing::subscriber::set_global_default(subscriber).unwrap();
#[cfg(feature = "tracing-log")]
tracing_log::LogTracer::init().unwrap();
let fut_a = spawn_fut("a", a);
pin_mut!(fut_a);
let waker = futures::task::noop_waker();
let mut cx = Context::from_waker(&waker);
assert!(fut_a.poll_unpin(&mut cx).is_pending());
let fut_b = spawn_fut("b", b);
pin_mut!(fut_b);
assert!(fut_b.poll_unpin(&mut cx).is_pending());
assert!(fut_a.poll_unpin(&mut cx).is_pending());
assert!(fut_b.poll_unpin(&mut cx).is_pending());
assert!(fut_a.poll_unpin(&mut cx).is_ready());
assert!(fut_b.poll_unpin(&mut cx).is_ready());
}
fn spawn_fut<F: Fn() -> Fut, Fut: Future<Output = ()>>(
key: &'static str,
inner: F,
) -> impl Future<Output = ()> {
let span = tracing::info_span!("spawn_fut", key);
async move {
countdown(1).await;
inner().await;
}
.instrument(span)
}
fn a() -> impl Future<Output = ()> {
let span = tracing::info_span!("a");
async move {
countdown(1).await;
tracing::info!("a");
}
.instrument(span)
}
fn b() -> impl Future<Output = ()> {
let span = tracing::info_span!("b");
async move {
countdown(1).await;
tracing::info!("b");
}
.instrument(span)
}
fn countdown(count: u32) -> impl Future<Output = ()> {
CountdownFuture { count }
}
struct CountdownFuture {
count: u32,
}
impl Future for CountdownFuture {
type Output = ();
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if self.count == 0 {
Poll::Ready(())
} else {
self.count -= 1;
cx.waker().wake_by_ref();
Poll::Pending
}
}
}
|