✨ promised fn
This commit is contained in:
parent
e3393f1e09
commit
0c190df5d7
4 changed files with 39 additions and 1 deletions
|
@ -84,6 +84,7 @@ pub fn worker(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
let init_fn = format_ident!("{}_init", fn_name);
|
let init_fn = format_ident!("{}_init", fn_name);
|
||||||
let init_fn_scoped = format_ident!("{}_init_scoped", fn_name);
|
let init_fn_scoped = format_ident!("{}_init_scoped", fn_name);
|
||||||
let fn_scope_struct = format_ident!("{}_Scoped", fn_name);
|
let fn_scope_struct = format_ident!("{}_Scoped", fn_name);
|
||||||
|
let fn_name_async = format_ident!("{}_async", fn_name);
|
||||||
let shutdown_fn = format_ident!("{}_shutdown", fn_name);
|
let shutdown_fn = format_ident!("{}_shutdown", fn_name);
|
||||||
|
|
||||||
let param_unpacking = param_names.iter().enumerate().map(|(i, name)| {
|
let param_unpacking = param_names.iter().enumerate().map(|(i, name)| {
|
||||||
|
@ -112,6 +113,12 @@ pub fn worker(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
serde_json::from_value(comrade::UNION.get(stringify!(#fn_name)).unwrap().send(i)).unwrap()
|
serde_json::from_value(comrade::UNION.get(stringify!(#fn_name)).unwrap().send(i)).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc = "Will run the function non blocking returning a `JobResult<_>` for fetching a result later."]
|
||||||
|
pub fn #fn_name_async(#(#param_names: #param_types),*) -> comrade::job::JobResult<comrade::serde_json::Value> {
|
||||||
|
let i: comrade::serde_json::Value = comrade::serde_json::to_value( (#(#param_names),*) ).unwrap();
|
||||||
|
comrade::UNION.get(stringify!(#fn_name)).unwrap().send_async(i)
|
||||||
|
}
|
||||||
|
|
||||||
fn #wrapper_fn(task: JobOrder<comrade::serde_json::Value, comrade::serde_json::Value>) {
|
fn #wrapper_fn(task: JobOrder<comrade::serde_json::Value, comrade::serde_json::Value>) {
|
||||||
let i = task.param.clone();
|
let i = task.param.clone();
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use comrade::{
|
use comrade::{
|
||||||
job::{JobDispatcher, JobOrder},
|
job::{JobDispatcher, JobOrder},
|
||||||
service::ServiceManager,
|
service::ServiceManager,
|
||||||
|
@ -5,6 +7,11 @@ use comrade::{
|
||||||
};
|
};
|
||||||
use crossbeam::channel::Receiver;
|
use crossbeam::channel::Receiver;
|
||||||
|
|
||||||
|
#[worker]
|
||||||
|
pub fn take_time(i: i32) {
|
||||||
|
std::thread::sleep(Duration::from_millis(i as u64));
|
||||||
|
}
|
||||||
|
|
||||||
#[worker]
|
#[worker]
|
||||||
pub fn myfn(i: i32) -> i32 {
|
pub fn myfn(i: i32) -> i32 {
|
||||||
i * 2
|
i * 2
|
||||||
|
@ -39,12 +46,19 @@ fn main() {
|
||||||
|
|
||||||
let s = ServiceManager::new().mode(comrade::service::ServiceMode::Decay);
|
let s = ServiceManager::new().mode(comrade::service::ServiceMode::Decay);
|
||||||
let s = myfn_init(s);
|
let s = myfn_init(s);
|
||||||
|
let s = take_time_init(s);
|
||||||
let s = s.spawn();
|
let s = s.spawn();
|
||||||
|
|
||||||
let x = myfn(55);
|
let x = myfn(55);
|
||||||
println!("myfn {x}");
|
println!("myfn {x}");
|
||||||
|
|
||||||
|
// decoupled
|
||||||
|
let e = take_time_async(1500);
|
||||||
|
println!("This will run right after!");
|
||||||
|
println!("the value is {}", e.wait());
|
||||||
|
|
||||||
myfn_shutdown();
|
myfn_shutdown();
|
||||||
|
take_time_shutdown();
|
||||||
|
|
||||||
s.join().unwrap();
|
s.join().unwrap();
|
||||||
}
|
}
|
||||||
|
|
18
src/job.rs
18
src/job.rs
|
@ -7,6 +7,15 @@ pub struct JobDispatcher<T: Send + 'static, V: Send + 'static> {
|
||||||
sender: Sender<JobOrder<T, V>>,
|
sender: Sender<JobOrder<T, V>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct JobResult<V>(std::sync::mpsc::Receiver<V>);
|
||||||
|
|
||||||
|
impl<V> JobResult<V> {
|
||||||
|
/// Wait for the Result of a Job.
|
||||||
|
pub fn wait(self) -> V {
|
||||||
|
self.0.recv().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Send + 'static, V: Send + 'static> JobDispatcher<T, V> {
|
impl<T: Send + 'static, V: Send + 'static> JobDispatcher<T, V> {
|
||||||
/// Creates a new instance of `JobDispatcher` and returns a tuple that contains it and a receiver end for `JobOrder`s.
|
/// Creates a new instance of `JobDispatcher` and returns a tuple that contains it and a receiver end for `JobOrder`s.
|
||||||
/// # Example:
|
/// # Example:
|
||||||
|
@ -48,6 +57,15 @@ impl<T: Send + 'static, V: Send + 'static> JobDispatcher<T, V> {
|
||||||
rx.recv().unwrap()
|
rx.recv().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn send_async(&self, param: T) -> JobResult<V> {
|
||||||
|
let (tx, rx) = mpsc::channel();
|
||||||
|
let job_order = JobOrder::new(param, move |ret| {
|
||||||
|
tx.send(ret).unwrap();
|
||||||
|
});
|
||||||
|
self.sender.send(job_order).unwrap();
|
||||||
|
JobResult(rx)
|
||||||
|
}
|
||||||
|
|
||||||
/// Sends a job of type `T` to the job dispatcher and waits for its result of type `V`.
|
/// Sends a job of type `T` to the job dispatcher and waits for its result of type `V`.
|
||||||
/// Returns `Some(V)` when the job returns an result, `None` if somehow nothing was returned or the internal `Mutex` is poisoned.
|
/// Returns `Some(V)` when the job returns an result, `None` if somehow nothing was returned or the internal `Mutex` is poisoned.
|
||||||
pub fn try_send(&self, param: T) -> Option<V> {
|
pub fn try_send(&self, param: T) -> Option<V> {
|
||||||
|
|
|
@ -8,7 +8,6 @@ use once_cell::sync::Lazy;
|
||||||
pub use serde_json;
|
pub use serde_json;
|
||||||
|
|
||||||
// TODO : worker docs + refactor
|
// TODO : worker docs + refactor
|
||||||
// TODO : worker non blocking fn call
|
|
||||||
// TODO : worker parallelism (Load Balanced Queue + Multiple Threads)
|
// TODO : worker parallelism (Load Balanced Queue + Multiple Threads)
|
||||||
// TODO : refactor dispatcher backends (memory, valkey)
|
// TODO : refactor dispatcher backends (memory, valkey)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue