#async #job #dependency #graph

async-jobs

Asynchronous job orchestration for Rust

2 unstable releases

0.2.0 Apr 12, 2021
0.1.0 Oct 18, 2020

#655 in Algorithms

MIT/Apache

29KB
562 lines

async-jobs

Asynchronous job orchestration for Rust

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual-licensed as above, without any additional terms or conditions.


lib.rs:

The async-jobs crate provides a framework for describing and executing a collection of interdependent and asynchronous jobs. It is intended to be used as the scheduling backbone for programs such as build systems which need to orchestrate arbitrary collections of tasks with complex dependency graphs.

The main way to use this crate is by creating implementations of the IntoJob trait to describe the tasks in your program and how they depend on one another. To run your jobs, create a Scheduler and pass a job to its run method.

Jobs are generic over the types C and E, which are the user-defined context and error types, respectively. The context mechanism provides a means for all jobs to access some shared bit of data; see Scheduler for more information. The error type allows jobs to return an arbitrary error value that is propagated up through the scheduler. Note that all jobs within the same job graph must use the same types for C and E.

Example

# use async_jobs::{Error, IntoJob, Outcome, Job, PlanBuilder, Scheduler};
#[derive(PartialEq)]
struct Foo(usize);

impl IntoJob<(), ()> for Foo {
    fn into_job(&self) -> Job<(), ()> {
        let num = self.0;
        Box::new(move |_| Box::pin(async move {
            println!("foo: {}", num);
            Ok(Outcome::Success)
        }))
    }
}

#[derive(PartialEq)]
struct Bar(usize);

impl IntoJob<(), ()> for Bar {
    fn plan(&self, plan: &mut PlanBuilder<(), ()>) -> Result<(), Error<()>> {
        plan.add_dependency(Foo(self.0 + 1))?;
        plan.add_dependency(Foo(self.0 + 2))?;
        Ok(())
    }

    fn into_job(&self) -> Job<(), ()> {
        let num = self.0;
        Box::new(move |_| Box::pin(async move {
            println!("bar: {}", num);
            Ok(Outcome::Success)
        }))
    }
}

let mut sched = Scheduler::new();
async_std::task::block_on(sched.run(Bar(7)));

Dependencies

~1MB
~18K SLoC