harmos_sidecar/kit/
task.rs1use std::{future::Future, io, sync::mpsc, thread};
18use tokio::{runtime::Builder, sync::oneshot, task::JoinHandle};
20use tracing::Instrument;
21struct Contextual<F: std::future::Future> {
32 future: Option<std::pin::Pin<Box<F>>>,
33 dispatcher: tracing::Dispatch,
34}
35
36trait InContext: std::future::Future + Sized {
41 fn in_context(self, dispatcher: tracing::Dispatch) -> Contextual<Self> {
42 Contextual { future: Some(Box::pin(self)), dispatcher }
43 }
44
45 fn in_current_context(self) -> Contextual<Self> {
46 self.in_context(tracing::dispatcher::get_default(Clone::clone))
47 }
48}
49
50impl<F: std::future::Future> InContext for F {}
53
54impl<F: std::future::Future> std::future::Future for Contextual<F> {
55 type Output = F::Output;
56
57 fn poll(self: std::pin::Pin<&mut Self>, context: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> {
58 let owner = self.get_mut();
59 let _dispatcher = tracing::dispatcher::set_default(&owner.dispatcher);
60 owner.future.as_mut().expect("context future remains until drop").as_mut().poll(context)
61 }
62}
63
64impl<F: std::future::Future> Drop for Contextual<F> {
65 fn drop(&mut self) {
66 tracing::dispatcher::with_default(&self.dispatcher, || drop(self.future.take()));
67 }
68}
69
70pub fn spawn(name: String, work: impl Future<Output = ()> + Send + 'static) -> io::Result<JoinHandle<()>> {
73 let work = work.instrument(tracing::Span::current()).in_current_context();
74 let (started, ready) = mpsc::sync_channel(1);
75 thread::Builder::new().name(name).spawn(move || {
76 let runtime = match Builder::new_current_thread().enable_all().build() {
77 Ok(runtime) => runtime,
78 Err(error) => {
79 let _ = started.send(Err(error));
80 return;
81 }
82 };
83 let (finished, completion) = oneshot::channel::<()>();
84 let task = runtime.spawn(async move {
85 let _finished = finished;
88 work.await;
89 });
90 if started.send(Ok(task)).is_err() {
91 return;
92 }
93
94 let _ = runtime.block_on(completion);
95 })?;
96
97 ready.recv().map_err(io::Error::other)?
98}
99
100