#![cfg(feature = "tokio")]
use eenn::{
CancellationToken, CompileTask, ExecutionContext, InMemoryProfiler, KernelCache,
spawn_precompile_worker,
};
use std::sync::Arc;
#[tokio::test]
async fn started_notify_allows_deterministic_cancel() {
let dir = tempfile::tempdir().expect("tmpdir");
let cache = KernelCache::new(dir.path()).expect("cache");
let cache = Arc::new(tokio::sync::Mutex::new(cache));
let profiler = Arc::new(InMemoryProfiler::new());
let ctx = Arc::new(ExecutionContext::with_profiler(profiler.clone()));
let compile_fn: std::sync::Arc<eenn::CompileFn> =
std::sync::Arc::new(|task: eenn::CompileTask| {
Box::pin(async move {
tokio::time::sleep(tokio::time::Duration::from_millis(200)).await;
let mut out = b"compiled:async:".to_vec();
out.extend_from_slice(task.fingerprint.as_bytes());
Ok(out)
})
});
let service = spawn_precompile_worker(cache.clone(), ctx.clone(), 1, compile_fn);
let (task, started, token) = CompileTask::with_started("deterministic", vec![]);
let (svc_tx, svc_rx) = tokio::sync::oneshot::channel();
tokio::spawn(async move {
let res = service.submit(task).await;
let _ = svc_tx.send((res, service));
});
started.notified().await;
token.cancel();
let (res, service) = svc_rx.await.expect("service spawn task dropped");
let _ = res;
let guard = cache.lock().await;
assert!(guard.lookup("deterministic").is_none());
service.shutdown().await;
}