Background Jobs

This crate provides tooling required to run some processes asynchronously from a usually synchronous application. The standard example of this is Web Services, where certain things need to be processed, but processing them while a user is waiting for their browser to respond might not be the best experience.

Usage

Add Background Jobs to your project

toml [dependencies] background-jobs = "0.1" failure = "0.1" futures = "0.1" tokio = "0.1"

To get started with Background Jobs, first you should define a job.

Jobs are a combination of the data required to perform an operation, and the logic of that operation. They implment the Job, serde::Serialize, and serde::DeserializeOwned.

```rust

[derive(Clone, Debug, Deserialize, Serialize)]

pub struct MyJob { someusize: usize, otherusize: usize, }

impl MyJob { pub fn new(someusize: usize, otherusize: usize) -> Self { MyJob { someusize, otherusize, } } }

impl Job for MyJob { fn run(self) -> Box + Send> { info!("args: {:?}", self);

    Box::new(Ok(()).into_future())
}

} ```

Next, define a Processor.

Processors are types that define default attributes for jobs, as well as containing some logic used internally to perform the job. Processors must implement Proccessor and Clone.

```rust

[derive(Clone, Debug)]

pub struct MyProcessor;

impl Processor for MyProcessor { // The kind of job this processor should execute type Job = MyJob;

// The name of the processor. It is super important that each processor has a unique name,
// because otherwise one processor will overwrite another processor when they're being
// registered.
fn name() -> &'static str {
    "MyProcessor"
}

// The queue that this processor belongs to
//
// Workers have the option to subscribe to specific queues, so this is important to
// determine which worker will call the processor
//
// Jobs can optionally override the queue they're spawned on
fn queue() -> &'static str {
    DEFAULT_QUEUE
}

// The number of times background-jobs should try to retry a job before giving up
//
// Jobs can optionally override this value
fn max_retries() -> MaxRetries {
    MaxRetries::Count(1)
}

// The logic to determine how often to retry this job if it fails
//
// Jobs can optionally override this value
fn backoff_strategy() -> Backoff {
    Backoff::Exponential(2)
}

} ```

Running jobs

By default, this crate ships with the background-jobs-server feature enabled. This uses the background-jobs-server crate to spin up a Server and Workers, and provides a mechanism for spawning new jobs.

Starting the job server

```rust use backgroundjobs::ServerConfig; use failure::Error; use serverjobsexample::queueset;

fn main() -> Result<(), Error> { // Run our job server tokio::run(ServerConfig::init( "127.0.0.1", 5555, 1, queue_set(), "example-db", ));

Ok(())

} ```

Starting the job worker

```rust use backgroundjobs::WorkerConfig; use failure::Error; use serverjobsexample::{queuemap, MyProcessor};

fn main() -> Result<(), Error> { // Create the worker config let mut worker = WorkerConfig::new("localhost".toowned(), 5555, queuemap());

// Register our processor
worker.register_processor(MyProcessor);

// Spin up the workers
tokio::run(worker.run());

Ok(())

} ```

Queuing jobs

```rust use backgroundjobs::SpawnerConfig; use futures::{future::lazy, Future}; use serverjobs_example::{MyJob, MyProcessor};

fn main() { // Create 50 new jobs, each with two consecutive values of the fibonacci sequence let (_, _, jobs) = (1..50).fold((0, 1, Vec::new()), |(x, y, mut acc), _| { acc.push(MyJob::new(x, y));

    (y, x + y, acc)
});

// Create the spawner
let spawner = SpawnerConfig::new("localhost", 5555);

// Queue each job
tokio::run(lazy(move || {
    for job in jobs {
        tokio::spawn(spawner.queue::<MyProcessor>(job).map_err(|_| ()));
    }

    Ok(())
}));

} ```

Not using a ZeroMQ based client/server model

If you want to create your own jobs processor based on this idea, you can depend on the background-jobs-core crate, which provides the LMDB storage, Processor and Job traits, as well as some other useful types for implementing a jobs processor.

Contributing

Feel free to open issues for anything you find an issue with. Please note that any contributed code will be licensed under the GPLv3.

License

Copyright © 2018 Riley Trautman

Background Jobs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Background Jobs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. This file is part of Background Jobs.

You should have received a copy of the GNU General Public License along with Background Jobs. If not, see http://www.gnu.org/licenses/.