Added untested comm impl

This commit is contained in:
2025-12-11 16:25:46 +01:00
parent 4e4dc381ea
commit d211f3127d
14 changed files with 613 additions and 61 deletions

42
orchid-base/src/stash.rs Normal file
View File

@@ -0,0 +1,42 @@
//! A pattern for running async code from sync destructors and other
//! unfortunately sync callbacks
//!
//! We create a task_local
use std::collections::VecDeque;
use std::pin::Pin;
use some_executor::task_local;
#[derive(Default)]
struct StashedFutures {
queue: VecDeque<Pin<Box<dyn Future<Output = ()>>>>,
}
task_local! {
static STASHED_FUTURES: StashedFutures;
}
/// Complete the argument future, and any futures spawned from it via [stash].
/// This is useful mostly to guarantee that messaging destructors have run.
pub async fn with_stash<F: Future>(fut: F) -> F::Output {
STASHED_FUTURES
.scope(StashedFutures::default(), async {
let val = fut.await;
while let Some(fut) = STASHED_FUTURES.with_mut(|sf| sf.unwrap().queue.pop_front()) {
fut.await;
}
val
})
.await
}
/// Schedule a future to be run before the next [with_stash] guard ends. This is
/// most useful for sending messages from destructors.
pub fn stash<F: Future + 'static>(fut: F) {
STASHED_FUTURES.with_mut(|sf| {
sf.expect("No stash! Timely completion cannot be guaranteed").queue.push_back(Box::pin(async {
fut.await;
}))
})
}