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
25        .into_iter()
26        .map(|item| {
27            let f = f.clone();
28            tokio::spawn(async move { f(item).await })
29        })
30        .collect();
31
32    let mut results = Vec::with_capacity(handles.len());
33    for handle in handles {
34        if let Ok(result) = handle.await {
35            results.push(result);
36        }
37    }
38    results
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44
45    fn double(x: i32) -> BoxFuture<i32> {
46        Box::pin(async move { x * 2 })
47    }
48
49    #[tokio::test]
50    async fn test_join_all_concurrent() {
51        let items = vec![1, 2, 3];
52        let result = join_all_concurrent(items, double).await;
53        assert_eq!(result, vec![2, 4, 6]);
54    }
55}