muffin/
lib.rs

1//! Muffin is a background job processing library designed to work with MongoDB as its storage backend.
2//!
3//! *Requires MongoDB 6 with feature compatibility level set to `6`.*
4//!
5//! # Features
6//! - Asynchronous processing using [`Tokio`](https://docs.rs/tokio/latest/tokio/)
7//! - Job objects serialized with [`Serde`](https://docs.rs/serde/latest/serde/)
8//! - [`Scheduled jobs`](Muffin::schedule())
9//! - [`Prioritized jobs`](Job::priority())
10//! - Retries with [`custom backoff strategies`](Job::backoff())
11//! - [`Unique jobs`](Job::unique_key())
12//!
13//! # Example
14//!
15//! ```no_run
16//! use std::sync::Arc;
17//!
18//! use async_trait::async_trait;
19//! use mongodb::{bson::doc, Client};
20//! use muffin::{Job, ProcessResult, Muffin, Status};
21//! use serde::{Deserialize, Serialize};
22//!
23//! struct JobState {
24//!     mongo_client: Client,
25//! }
26//!
27//! #[derive(Serialize, Deserialize)]
28//! struct MyJob {
29//!     name: String,
30//! }
31//!
32//! #[async_trait]
33//! impl Job for MyJob {
34//!     type State = Arc<JobState>;
35//!
36//!     fn id() -> &'static str
37//!     where
38//!        Self: Sized,
39//!     {
40//!         // A unique identifier of the job
41//!         "MyJob"
42//!     }
43//!
44//!     async fn process(&self, state: Self::State) -> ProcessResult {
45//!        // Do something with self.name and state
46//!        Ok(Status::Completed)
47//!     }
48//! }
49//!
50//! #[tokio::main]
51//! async fn main() -> muffin::Result<()> {
52//!     // Connect to a database called "muffin_testing".
53//!     let client = Client::with_uri_str("mongodb://localhost:27017").await?;
54//!     let database = client.database("muffin_testing");
55//!
56//!     // The state is passed to each "process" method on an instance of Job.
57//!     let state = JobState {
58//!         mongo_client: client,
59//!     };
60//!     let mut muffin = Muffin::new(database, Arc::new(state)).await?;
61//!
62//!     // Create a new job and push it for processing
63//!     muffin
64//!         .push(MyJob {
65//!             name: "Peter".into(),
66//!         })
67//!         .await?;
68//!
69//!     // Register jobs that should be processed.
70//!     muffin.register::<MyJob>();
71//!
72//!     // Start processing jobs.
73//!     tokio::select! {
74//!         _ = muffin.run() => {},
75//!         _ = tokio::signal::ctrl_c() => {
76//!             eprintln!("Received ctrl+c!");
77//!         }
78//!     };
79//!
80//!     // Need to wait for all in-flight jobs to finish processing.
81//!     muffin.shutdown().await;
82//!
83//!     Ok(())
84//! }
85//!```
86//!
87//! You can find other examples in the [`repository`](https://github.com/jiripospisil/muffin/tree/master/examples).
88
89pub mod backoff;
90mod config;
91mod db;
92mod job;
93mod muffin;
94mod types;
95
96pub use crate::muffin::Muffin;
97pub use config::{Config, ConfigBuilder};
98pub use job::Job;
99pub use types::{Error, JobPersistedStatus, ProcessResult, Result, Schedule, Status};