Jobs
Jobs
represent some work packaged up in a function that the application
has to execute but it's not necessary to hold up the response to the user.
Just like middleware
, jobs
are bound to a Request
or a Response
and
utilize the same argument system as middleware
.
We have 3 types of jobs
based on their behaviour.
This is necessary to have an optimal way of using our resources.
- Job
Future
that does not block and does not perform any significant intensive work . It is queued on the regular tokio runtime.CpuBound
is a type of function that would do heavy computation and does not benefit from the tokio runtime. We would execute those on theRayon
runtime that is optimized for that.IOBlocking
is suitable for various kinds of IO operations that cannot be performed asynchronously. It is executed on a separate tokio blocking threads.
While i recommend using the macros. If you really want to, you could implement the Job factory request and response traits.
#![allow(unused)] fn main() { pub enum Job<T = ()> { Future(FutureJob<T>), CpuBound(CpuJob<T>), IOBlocking(IOBlockingJob<T>), } pub struct FutureJob<T = ()>(Pin<Box<dyn Future<Output = T> + Send>>); pub struct CpuJob<T = ()>(Box<dyn FnOnce() -> T + Send>); pub struct IOBlockingJob<T = ()>(Box<dyn FnOnce() -> T + Send>); }
Few short examples.
#![allow(unused)] fn main() { #[job_factory(Request)] async fn first_async_job() -> FutureJob { async { println!("first job in the background.") }.into() } }
// blocking here is ok!
#![allow(unused)] fn main() { #[job_factory(Response)] async fn first_sync_job(#[response] r: &Response<Body>) -> IOBlockingJob { let status_code = r.status(); let job = move || { std::thread::sleep(std::time::Duration::from_secs(2)); println!( "first_sync_job in the background for a request with status {}", status_code ); }; job.into() } }
#![allow(unused)] fn main() { #[job_factory(Response)] async fn my_heavy_computation() -> CpuJob { let job = || { for _ in 0..100 { let mut r = 0; for _ in 0..10000000 { r += 1; } println!("my_heavy_computation runs in the background. {}", r); } }; job.into() } }