use std::fmt::Debug; use std::sync::Arc; use init_once::InitOnce; use tokio::time; struct AnnounceDrop { value: T, } #[tokio::main] async fn main() { let init_once = Arc::new(InitOnce::new()); let threads: Vec<_> = (0..10) .map(|i| { let init_once = Arc::clone(&init_once); tokio::spawn(async move { let worker_sleep_dur = time::Duration::from_secs(i); println!("I am thread {i}, sleeping for {worker_sleep_dur:?}"); time::sleep(worker_sleep_dur).await; let maybe_value = init_once .try_init_async(async { time::sleep(time::Duration::from_secs(5)).await; println!("Took a second but we out here"); AnnounceDrop { value: format!("I am thread {i}, blazing 420"), } }) .await; if let Some(AnnounceDrop { value }) = maybe_value { println!("Read {value:?} from {i}"); } else { println!("Thread {i} couldn't read value"); } }) }) .collect(); for handle in threads { handle.await.unwrap(); } } impl Drop for AnnounceDrop { fn drop(&mut self) { println!("Dropping value: {:?}", self.value); } }