use std::{sync::mpsc, thread, time::Instant}; pub mod job; pub mod service; pub use comrade_macro::worker; use dashmap::DashMap; use once_cell::sync::Lazy; pub use serde_json; // TODO : worker docs + refactor // TODO : worker non blocking fn call // TODO : worker parallelism (Load Balanced Queue + Multiple Threads) // TODO : refactor dispatcher backends (memory, valkey) pub static UNION: Lazy< DashMap<&'static str, job::JobDispatcher>, > = Lazy::new(DashMap::new); /// Rally Function /// /// This executes a thread for every item executing `f(&item) -> X`. Whatever function returns first is returned while every other thread is killed. pub fn rally(items: Vec, f: F) -> (T, X) where F: Fn(&T) -> X + Send + Sync + Copy + 'static, { let (tx, rx) = mpsc::channel(); let items_len = items.len(); let mut handles = Vec::new(); for item in items { let tx = tx.clone(); let item_ref = item; let f = f; let handle = thread::spawn(move || { let start = Instant::now(); let result = f(&item_ref); let elapsed = start.elapsed(); let _ = tx.send((item_ref, result, elapsed)); }); handles.push(handle); } drop(tx); let (fastest_item, fastest_result, elapsed) = rx.recv().unwrap(); for handle in handles { handle.thread().unpark(); } log::info!("Rally ended with {items_len} items in {elapsed:?}"); (fastest_item, fastest_result) } // TODO : async version /* pub fn rally_async(items: Vec, f: F) -> (T, X) where F: AsyncFn(&T) -> X + Send + Sync + Copy + 'static, { let (tx, rx) = mpsc::channel(); let mut handles = Vec::new(); for item in items { let tx = tx.clone(); let item_ref = item; let f = f; tokio::task::spawn() let handle = thread::spawn(move || { let start = Instant::now(); let result = f(&item_ref); let elapsed = start.elapsed(); let _ = tx.send((item_ref, result, elapsed)); }); handles.push(handle); } drop(tx); let (fastest_item, fastest_result, _) = rx.recv().unwrap(); for handle in handles { handle.thread().unpark(); } (fastest_item, fastest_result) } */