Update tests, examples, benches
This commit is contained in:
1 parent
0137296fb4
commit
86787b3a0d
71 files changed
+1791
-3547
No files matched your search
+12
-87
@@ -1,14 +1,20 @@
|
||||
//! Tests for timing and speedup verification
|
||||
|
||||
use crate::common::task_fn;
|
||||
|
||||
use dagx::{DagResult, DagRunner, TaskHandle};
|
||||
use dagx::{task, DagResult, DagRunner};
|
||||
use futures::FutureExt;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use std::time::{Duration, Instant};
|
||||
use tokio::time::sleep;
|
||||
|
||||
struct SleepTask(usize, Duration);
|
||||
|
||||
#[task]
|
||||
impl SleepTask {
|
||||
async fn run(&self) -> usize {
|
||||
sleep(self.1).await;
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_parallel_execution_speedup() -> DagResult<()> {
|
||||
// Prove parallel execution by comparing timing
|
||||
@@ -19,12 +25,7 @@ async fn test_parallel_execution_speedup() -> DagResult<()> {
|
||||
|
||||
// Create independent tasks that each take 50ms
|
||||
let tasks: Vec<_> = (0..num_tasks)
|
||||
.map(|i| {
|
||||
dag.add_task(task_fn(move |_: ()| async move {
|
||||
sleep(work_duration).await;
|
||||
i
|
||||
}))
|
||||
})
|
||||
.map(|i| dag.add_task(SleepTask(i, work_duration)))
|
||||
.collect();
|
||||
|
||||
let start = Instant::now();
|
||||
@@ -55,79 +56,3 @@ async fn test_parallel_execution_speedup() -> DagResult<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct SyncTask;
|
||||
#[dagx::task]
|
||||
impl SyncTask {
|
||||
fn run(&self, x: &i32) -> i32 {
|
||||
// Synchronous task - no async/await
|
||||
std::thread::sleep(Duration::from_millis(1)); // Blocking sleep
|
||||
x * 2
|
||||
}
|
||||
}
|
||||
|
||||
struct AsyncTask;
|
||||
#[dagx::task]
|
||||
impl AsyncTask {
|
||||
async fn run(&self, x: &i32) -> i32 {
|
||||
// Async task
|
||||
sleep(Duration::from_millis(1)).await; // Non-blocking sleep
|
||||
x * 3
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_sync_tasks_dont_block_async_runtime() -> DagResult<()> {
|
||||
// Test that sync tasks don't block the async runtime
|
||||
let dag = DagRunner::new();
|
||||
|
||||
let start_times = Arc::new(Mutex::new(Vec::new()));
|
||||
|
||||
// Mix of sync and async tasks
|
||||
let source: TaskHandle<_> = dag.add_task(task_fn(|_: ()| async { 10 })).into();
|
||||
|
||||
// Sync tasks
|
||||
let sync1 = dag.add_task(SyncTask).depends_on(source);
|
||||
let sync2 = dag.add_task(SyncTask).depends_on(source);
|
||||
|
||||
// Async tasks
|
||||
let async1 = dag.add_task(AsyncTask).depends_on(source);
|
||||
let async2 = dag.add_task(AsyncTask).depends_on(source);
|
||||
|
||||
// Track timing
|
||||
let timing_task = {
|
||||
let times = start_times.clone();
|
||||
dag.add_task(task_fn(move |_: ()| {
|
||||
let times = times.clone();
|
||||
async move {
|
||||
for i in 0..5 {
|
||||
times
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push((format!("tick_{}", i), Instant::now()));
|
||||
sleep(Duration::from_millis(5)).await;
|
||||
}
|
||||
"timing"
|
||||
}
|
||||
}))
|
||||
};
|
||||
|
||||
dag.run(|fut| tokio::spawn(fut).map(Result::unwrap)).await?;
|
||||
|
||||
// Verify results
|
||||
assert_eq!(dag.get(sync1)?, 20);
|
||||
assert_eq!(dag.get(sync2)?, 20);
|
||||
assert_eq!(dag.get(async1)?, 30);
|
||||
assert_eq!(dag.get(async2)?, 30);
|
||||
assert_eq!(dag.get(timing_task)?, "timing");
|
||||
|
||||
// Check that timing task made progress (wasn't blocked by sync tasks)
|
||||
let times = start_times.lock().unwrap();
|
||||
assert_eq!(
|
||||
times.len(),
|
||||
5,
|
||||
"Timing task should have completed all ticks"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in new issue
Block a user