93 lines
2.4 KiB
Rust
93 lines
2.4 KiB
Rust
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<serde_json::Value, serde_json::Value>>,
|
|
> = 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<T: Send + Sync + 'static, F, X: Send + 'static>(items: Vec<T>, 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<T: Send + Sync + 'static, F, X: Send + 'static>(items: Vec<T>, 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)
|
|
}
|
|
|
|
*/
|