pub async fn check_cancel_safe<F, Fut, AssertFn>(
name: impl Into<String>,
cancel_at: Duration,
fut: Fut,
assert_safe: AssertFn,
) -> CheckResultExpand description
Drive fut for at most cancel_at duration, then drop it. After
the drop, run assert_safe to ask the caller whether the
observable state is still consistent. Emit a CheckResult.
Verdicts:
assert_safe()returnstrue->Passwithcancellation_safe.assert_safe()returnsfalse->Fail (Critical)withcancellation_unsafe+regressiontags. State has been corrupted by the cancellation.futcompletes beforecancel_at->Skipwith detail (“future completed before cancellation”). The check did not exercise cancellation; tightencancel_ator run a slower future.
assert_safe is invoked synchronously after the future has been
dropped. It must not panic.
§Example
use dev_async::cancellation_safety::check_cancel_safe;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::time::Duration;
let counter = Arc::new(AtomicUsize::new(0));
let c2 = counter.clone();
let check = check_cancel_safe(
"buffered_write",
Duration::from_millis(20),
async move {
c2.fetch_add(1, Ordering::SeqCst);
tokio::time::sleep(Duration::from_secs(1)).await;
c2.fetch_add(1, Ordering::SeqCst); // never reached if cancelled
},
|| counter.load(Ordering::SeqCst) <= 1,
).await;
assert!(check.has_tag("async"));