// 独立 Tokio 参照只实现本组一层任务工作负载,不调用 Dever 调度器。 // 任务和 worker 分别限流;遇到失败或取消仍领取所有 JoinHandle,已启动阻塞工作不强停。 use std::{sync::Arc, time::Duration}; use tokio::{runtime, sync::Semaphore, task::JoinHandle}; use tokio_util::sync::CancellationToken; struct NativeTasks { runtime: runtime::Runtime, workers: Arc, tasks: Arc, } fn task_fault(_: impl std::fmt::Debug) -> Fault { &FaultInfo { source: "task-reference", line: 1, column: 1, message: "task failure", } } fn native_total(values: &[i64]) -> Result { values.iter().try_fold(0i64, |total, value| { total .checked_add(*value) .ok_or_else(|| task_fault("integer overflow")) }) } impl NativeTasks { fn new() -> Self { Self { runtime: runtime::Builder::new_multi_thread() .worker_threads(2) .max_blocking_threads(2) .enable_time() .build() .unwrap(), workers: Arc::new(Semaphore::new(2)), tasks: Arc::new(Semaphore::new(8)), } } fn start( &self, values: Vec, asynchronous: bool, cancel: CancellationToken, ) -> JoinHandle> { let admission = self.tasks.clone().try_acquire_owned().unwrap(); let workers = self.workers.clone(); tokio::spawn(async move { let result = if asynchronous { tokio::select! { biased; result = async { native_total(&values) } => result, () = cancel.cancelled() => Err(task_fault("cancelled")), } } else { let worker = tokio::select! { biased; () = cancel.cancelled() => return Err(task_fault("cancelled")), worker = workers.acquire_owned() => worker.unwrap(), }; let result = tokio::task::spawn_blocking(move || native_total(&values)) .await .map_err(task_fault)?; drop(worker); result }; drop(admission); result }) } fn pair(&self, values: &[i64], asynchronous: bool) -> Result { self.runtime.block_on(async { let cancel = CancellationToken::new(); let first = self.start(values.to_vec(), asynchronous, cancel.child_token()); let second = self.start(values.to_vec(), asynchronous, cancel.child_token()); let first = first.await.map_err(task_fault).and_then(|value| value); if first.is_err() { cancel.cancel(); } let second = second.await.map_err(task_fault).and_then(|value| value); cancel.cancel(); first? .checked_add(second?) .ok_or_else(|| task_fault("integer overflow")) }) } fn blocking(&self, values: &[i64], sleep: bool) -> Result { let values = values.to_vec(); self.runtime.block_on(async { let worker = self.workers.clone().acquire_owned().await.unwrap(); let result = tokio::task::spawn_blocking(move || { if sleep { std::time::Instant::now() .checked_add(Duration::ZERO) .ok_or_else(|| task_fault("sleep deadline"))?; std::thread::sleep(Duration::ZERO); } native_total(&values) }) .await .map_err(task_fault)?; drop(worker); result }) } fn cancel(&self) -> Result { self.runtime.block_on(async { let admission = self.tasks.clone().try_acquire_owned().unwrap(); let cancel = CancellationToken::new(); let child = cancel.child_token(); let task = tokio::spawn(async move { let deadline = tokio::time::Instant::now() .checked_add(Duration::from_millis(60000)) .unwrap(); tokio::select! { biased; () = tokio::time::sleep_until(deadline) => panic!("cancelled timer completed"), () = child.cancelled() => (), } drop(admission); }); cancel.cancel(); task.await.map_err(task_fault)?; Ok(1) }) } fn timer(&self) -> Result { self.runtime.block_on(async { let deadline = tokio::time::Instant::now() .checked_add(Duration::ZERO) .ok_or_else(|| task_fault("sleep deadline"))?; tokio::time::sleep_until(deadline).await; Ok(1) }) } }