use std::fmt::Debug;
use std::sync::Arc;
use init_once::InitOnce;
use tokio::time;
struct AnnounceDrop<T: Debug> {
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<T: Debug> Drop for AnnounceDrop<T> {
fn drop(&mut self) {
println!("Dropping value: {:?}", self.value);
}
}