1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
#![deny(missing_docs, dead_code)] //! Marid //! //! A process orchestration library. //! //! This library is influenced by [tedsuo's ifrit](https://github.com/tedsuo/ifrit), a similar //! library for Golang. //! //! The foundation of the library is built on the idea of a `Runner` trait, which //! encapsulates a singular unit of work, e.g. a thread, which is has a long lifetime, potentially //! forever. The `Process` is a trait that defines the actual running of one or more `Runner` //! objects. Importantly, a `Process` defines the ability to wait for, and signal a //! `Runner`. //! //! # Examples //! //! ``` //! use marid::{launch, Runner, Process, Composer, FnRunner, Signal}; //! //! let mut runner1 = Box::new(FnRunner::new(move |_sig| { //! // Do a bunch of work... //! Ok(()) //! })) as Box<Runner + Send>; //! //! let mut runner2 = Box::new(FnRunner::new(move |_sig| { //! // Do a bunch of other work... //! Ok(()) //! })) as Box<Runner + Send>; //! //! let composer = Composer::new(vec!(runner1, runner2), Signal::INT); //! let signals = vec!(Signal::INT, Signal::ALRM); //! //! // Start all Runners in separate threads. //! let process = launch(composer, signals); //! //! // Wait until all Runners have been setup. //! assert!(process.ready().is_ok()); //! //! // Send a shutdown signal to all Runners. //! process.signal(Signal::INT); //! //! // Wait until all Runners have finished. //! assert!(process.wait().is_ok()); //! ``` #[macro_use] extern crate chan; extern crate chan_signal; extern crate crossbeam; mod traits; pub use traits::{Signal, Sender, Receiver, Process, Runner}; mod thunk; mod fn_runner; pub use fn_runner::FnRunner; mod composer; pub use composer::Composer; mod process; pub use process::{MaridProcess, ProcessError}; use std::error::Error; /// Error type for Marid Runners. pub type MaridError = Box<Error + Send>; /// Launch the specified runner as well as listen on the specified signals. /// /// # Safety /// /// This must be called before any threads are spawned in the process to /// ensure appropriate signal handling behavior. pub fn launch<R>(runner: R, signals: Vec<Signal>) -> MaridProcess where R: Runner + Send + 'static { let (signal_send, signal_recv) = chan::sync(1024); for sig in signals { chan_signal::notify_on(&signal_send, sig); } MaridProcess::start(Box::new(runner), signal_send, signal_recv) } // TODO: Make this module more useable and document behavior. pub mod test_helpers;