use futures::future::join_all;
use serde_json::Value;
use std::collections::VecDeque;
use std::sync::Arc;
use tokio::sync::{Mutex, Semaphore};
use tokio::time::{sleep, Duration};
use tracing::{error, info};
pub struct ParallelExecutor {
semaphore: Arc<Semaphore>,
retry_queue: Arc<Mutex<VecDeque<Value>>>,
}
impl ParallelExecutor {
pub fn new(parallel_limit: usize) -> Self {
Self {
semaphore: Arc::new(Semaphore::new(parallel_limit)),
retry_queue: Arc::new(Mutex::new(VecDeque::new())),
}
}
pub async fn execute_parallel(&self, operations: Vec<Value>) -> Vec<Result<Value, String>> {
info!("🚀 Turbo: Executing {} operations in parallel", operations.len());
let tasks: Vec<_> = operations
.into_iter()
.map(|op| {
let sem = self.semaphore.clone();
async move {
let _permit = match sem.acquire().await {
Ok(permit) => permit,
Err(e) => {
error!("Failed to acquire semaphore: {}", e);
return Err(format!("Semaphore error: {e}"));
}
};
self.execute_single(op).await
}
})
.collect();
join_all(tasks).await
}
async fn execute_single(&self, operation: Value) -> Result<Value, String> {
let mut retry_count = 0;
const MAX_RETRIES: u32 = 3;
loop {
match self.perform_operation(&operation).await {
Ok(result) => return Ok(result),
Err(e) if retry_count < MAX_RETRIES => {
retry_count += 1;
let delay = Duration::from_millis(100 * (2_u64.pow(retry_count)));
info!("Retry {}/{} after {:?}: {}", retry_count, MAX_RETRIES, delay, e);
sleep(delay).await;
}
Err(e) => {
error!("Operation failed after {} retries: {}", MAX_RETRIES, e);
return Err(e);
}
}
}
}
async fn perform_operation(&self, operation: &Value) -> Result<Value, String> {
if let Some(method) = operation.get("method").and_then(|m| m.as_str()) {
match method {
"file.edit" => {
Ok(serde_json::json!({
"success": true,
"file": operation.get("params").and_then(|p| p.get("file")),
"turbo": true
}))
}
"command.execute" => {
Ok(serde_json::json!({
"success": true,
"output": "Command executed",
"turbo": true
}))
}
_ => Err(format!("Unknown method: {method}")),
}
} else {
Err("No method specified".to_string())
}
}
pub async fn queue_retry(&self, operation: Value) {
self.retry_queue.lock().await.push_back(operation);
}
pub async fn process_retries(&self) -> Vec<Result<Value, String>> {
let mut queue = self.retry_queue.lock().await;
let operations: Vec<Value> = queue.drain(..).collect();
drop(queue);
if !operations.is_empty() {
info!("Processing {} queued retries", operations.len());
self.execute_parallel(operations).await
} else {
Vec::new()
}
}
}