Skip to main content

ai_agent/utils/
concurrent.rs

1// Source: /data/home/swei/claudecode/openclaudecode/src/utils/generators.ts
2//! Concurrent execution utilities for running multiple async operations with a concurrency limit.
3//!
4//! Translated from TypeScript generators.ts
5
6use std::sync::Arc;
7use tokio::sync::Mutex;
8
9/// Type alias for boxed futures
10pub type BoxFuture<T> = std::pin::Pin<Box<dyn std::future::Future<Output = T> + Send>>;
11
12/// Simple concurrent batch that spawns all tasks at once
13/// Returns results in input order
14pub async fn join_all_concurrent<T, R, F>(items: Vec<T>, f: F) -> Vec<R>
15where
16    T: Send + 'static,
17    R: Send + 'static,
18    F: Fn(T) -> BoxFuture<R> + Send + Clone + 'static,
19{
20    if items.is_empty() {
21        return vec![];
22    }
23
24    let handles: Vec<_> = items.into_iter().map(|item| {
25        let f = f.clone();
26        tokio::spawn(async move {
27            f(item).await
28        })
29    }).collect();
30
31    let mut results = Vec::with_capacity(handles.len());
32    for handle in handles {
33        if let Ok(result) = handle.await {
34            results.push(result);
35        }
36    }
37    results
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43
44    fn double(x: i32) -> BoxFuture<i32> {
45        Box::pin(async move { x * 2 })
46    }
47
48    #[tokio::test]
49    async fn test_join_all_concurrent() {
50        let items = vec![1, 2, 3];
51        let result = join_all_concurrent(items, double).await;
52        assert_eq!(result, vec![2, 4, 6]);
53    }
54}