2 releases
0.1.2 | Nov 29, 2019 |
---|---|
0.1.1 | Nov 29, 2019 |
#43 in #task-runner
38KB
609 lines
Izta - Rust Asynchronous Task Scheduler
Izta is a drop-in asynchronous job queue for Rust. It is designed to run in the vast majority of Rust applications without changes to software architecture or system infrastructure. It can run inside your application process as a separate thread or by itself on a separate server. Multiple instances may run concurrently to execute tasks in parallel. Izta also implements named queues, so that tasks in one queue can be processed by Izta instance A and those in another queue by Izta instance B - allowing busy queues to be scaled out separately from others. Currently, Postgres is the only supported backend.
Examples
Before starting the job queue, the jobs themselves need to be defined. Any struct that
implements the Job
(see Job
documentation for more details), Serialize
and
Deserialize
traits are valid Job types.
Here's an example of a job that simply divides two numbers together:
#[macro_use] extern crate serde;
use izta::job::Job;
// Jobs can be any type that implements the Job, Serialize and Deserialize traits
#[derive(Serialize, Deserialize)]
struct DivideJob {
a: i64,
b: i64,
}
// Jobs must have a serializable error type. Could be `()` for jobs that always succeed
#[derive(Serialize, Deserialize)]
enum DivideJobErr {
DivideByZero,
}
impl Job for DivideJob {
// Specify the result and error types
type R = i64;
type E = DivideJobErr;
// All jobs must have a UUID
const UUID: &'static str = "74f3a15b-75c0-4889-9546-63b02ff304e4";
const MAX_ATTEMPTS: usize = 3;
// Job logic - return an `Err` for errors and `Ok` if successful.
fn run(&self) -> Result<Self::R, Self::E> {
if self.b == 0 {
return Err(DivideJobErr::DivideByZero);
}
Ok(self.a / self.b)
}
}
With a job defined, we can now create a task runner:
#
#
#
#
#
#
use izta::process_jobs;
use izta::runner::Runner;
let runner = Runner::new(
process_jobs!(DivideJob),
"postgres://izta:password@localhost:5432/izta_test",
"tasks",
vec![],
);
Defining and adding tasks is easy with TaskReq::new
:
#
#
#
#
#
#
use izta::task::task_req::TaskReq;
let task_req = TaskReq::new(DivideJob { a: 1, b: 2 });
runner.add_task(&task_req);
Starting the task runner will begin executing tasks
#
#
#
#
#
#
#
runner.start();
Of course, it's possible to add new tasks after the task runner has been started.
Running start()
multiple times will spawn multiple instances of the task runner that will
execute tasks in parallel.
Dependencies
~7.5MB
~152K SLoC