Initial Dever 0.0.1

This commit is contained in:
Codex committed 2026-11-03 03:32:07 +00:00
commit 81233d098c
1479 files changed
+163782

No files matched your search

+102
View File
@@ -0,0 +1,102 @@
// 独立使用 Tokio 的取消与排空参照;不调用 Dever 的 Scope、Task 或生成函数。
use tokio_util::task::{AbortOnDropHandle, task_tracker::TaskTrackerToken};
impl NativeTasks {
fn tracked_leaf<Value, Work>(
&self,
tasks: &TaskTracker,
call: impl FnOnce() -> Work + Send + 'static,
) -> Result<AbortOnDropHandle<(Value, TaskTrackerToken)>, Fault>
where
Value: Send + 'static,
Work: std::future::Future<Output = Value> + Send + 'static,
{
if tasks.is_closed() {
return Err(task_fault("closed task scope"));
}
let permit = self.tasks.clone().try_acquire_owned().map_err(task_fault)?;
let tracking = tasks.token();
let future = async move {
let result = call().await;
drop(permit);
result
};
// Future 先释放;未领取的输出也必须先于跟踪令牌释放。
Ok(AbortOnDropHandle::new(tokio::spawn(
future.map(move |result| (result, tracking)),
)))
}
}
fn reference_cancel_scoped(values: &[TaskCase]) -> Result<i64, Fault> {
let Some(value) = values.first() else { return Ok(0); };
value.native.worker_scope(async |tasks| {
let task = value.native.tracked_leaf(tasks, || native_fallible_sleep(60000))?;
task.abort();
match task.await {
Err(error) if error.is_cancelled() => (),
Err(error) => return Err(NativeAsyncFailure::Fault(task_fault(error))),
Ok((result, _tracking)) => result?,
}
Ok::<_, NativeAsyncFailure>(1)
})?.map_err(Into::into)
}
fn cancel_scoped(cases: &[TaskCase]) {
compare_named("task_cancel_scoped", cases, 1000,
generated_cancel, reference_cancel_scoped, |value| *value as u64, "rust_scoped");
}
fn check_cancel_cleanup() {
let native = NativeTasks::new();
native.worker_scope(async |tasks| {
let task = native.tracked_leaf(tasks, || async { 42 }).unwrap();
let (value, tracking) = task.await.unwrap();
assert_eq!(value, 42);
drop(tracking);
let permits = native.tasks.clone().acquire_many_owned(8).await.unwrap();
assert!(native.tracked_leaf(tasks, || async {}).is_err());
drop(permits);
tasks.close();
assert!(native.tracked_leaf(tasks, || async {}).is_err());
}).unwrap();
// 立即放弃、已启动 Future、未领取输出分别验证,根 panic 也必须排空。
for stage in 0..3 {
for root_panics in [false, true] {
let dropped = Arc::new(AtomicBool::new(false));
let observed = dropped.clone();
let owned = WorkerOutput(dropped);
let outcome = native.worker_scope(async |tasks| {
let (started, ready) = tokio::sync::oneshot::channel();
let task = native.tracked_leaf(tasks, move || async move {
if stage != 0 { started.send(()).unwrap(); }
if stage != 2 { std::future::pending::<()>().await; }
owned
}).unwrap();
if stage != 0 { ready.await.unwrap(); }
if stage == 2 {
while !task.is_finished() { tokio::task::yield_now().await; }
assert!(!observed.load(Ordering::SeqCst));
}
if root_panics { panic!("root failure after leaf submission"); }
drop(task);
});
assert_eq!(outcome.is_err(), root_panics);
assert!(observed.load(Ordering::SeqCst));
assert_eq!(native.tasks.available_permits(), 8);
}
}
native.worker_scope(async |tasks| {
let task = native.tracked_leaf(tasks, || async { Err::<(), _>("business failure") }).unwrap();
while !task.is_finished() { tokio::task::yield_now().await; }
task.abort();
let (result, tracking) = task.await.unwrap();
assert_eq!(result, Err("business failure"));
drop(tracking);
let task = native.tracked_leaf(tasks, || async { panic!("leaf failure") }).unwrap();
assert!(task.await.unwrap_err().is_panic());
}).unwrap();
println!("leaf cleanup: capacity, closed scope, inputs, future, unclaimed output, root panic, business error, task panic and re-entry passed");
}