pgboss/lib.rs
1//! Queue jobs with Rust and PostgreSQL like a boss.
2//!
3//! Inspired by, compatible with and partially ported from [`pg-boss`](https://github.com/timgit/pg-boss/tree/master) Node.js package.
4//!
5//! Heavily influenced by decisions and approaches in [`faktory-rs`](https://github.com/jonhoo/faktory-rs) crate.
6//!
7//! ```no_run
8//! # tokio_test::block_on(async {
9//! use std::time::Duration;
10//! use serde_json::json;
11//! use pgboss::{Client, Job, JobState};
12//!
13//! // Create a client first.
14//! let c = Client::builder().schema("desired_schema_name").connect().await.unwrap();
15//!
16//! // Then create a queue.
17//! c.create_standard_queue("qname").await.unwrap();  // NB! queue should be created before pushing jobs
18//! c.create_standard_queue("qname_dlq").await.unwrap();
19//!
20//! // Build a job and ...
21//! let job = Job::builder()
22//!     .queue_name("qname")                           // which queue this job should be sent to
23//!     .data(json!({"key": "value"}))                 // arbitrary json, your job's payload
24//!     .priority(10)                                  // will be consumer prior to those with lower priorities
25//!     .retry_limit(1)                                // only retry this job once
26//!     .dead_letter("qname_dlq")                      // send to this queue when retry limit exceeded
27//!     .retry_delay(Duration::from_secs(60 * 5))      // do not retry immediately after failure
28//!     .expire_in(Duration::from_secs(60 * 5))        // only give the worker 5 minutes to complete the job
29//!     .retain_for(Duration::from_secs(60 * 60 * 24)) // do not archive for at least 1 day
30//!     .delay_for(Duration::from_secs(5))             // make it visible to consumers after 5 seconds
31//!     .singleton_for(Duration::from_secs(7))         // only allow one job for at least 7 seconds
32//!     .singleton_key("buzz")                         // allow more than one job if their key is different from this
33//!     .build();
34//!
35//! // ... enqueue it.
36//! let _id = c.send_job(&job).await.expect("no error");
37//!
38//! // Consume from the queue.
39//! let fetched_job = c
40//!     .fetch_job("qname")
41//!     .await
42//!     .expect("no error")
43//!     .expect("a job");
44//!
45//! assert_eq!(fetched_job.data, job.data);
46//! assert_eq!(fetched_job.state, JobState::Active);
47//!
48//! c.complete_job("qname", fetched_job.id, json!({"result": "success!"})).await.expect("no error");
49//! # });
50//! ```
51//!
52#![deny(missing_docs)]
53#![cfg_attr(docsrs, feature(doc_cfg))]
54
55mod client;
56mod error;
57mod job;
58mod queue;
59mod sql;
60mod utils;
61
62pub use client::{Client, ClientBuilder, MaintenanceStats};
63pub use error::Error;
64pub use job::{Job, JobBuilder, JobDetails, JobState};
65pub use queue::{Queue, QueueBuilder, QueueDetails, QueuePolicy};
66
67use chrono::{DateTime, Utc};
68use sqlx::FromRow;
69use std::fmt::Debug;
70
71pub(crate) use job::JobOptions;
72// https://github.com/timgit/pg-boss/blob/4b3d9f4628860bb103f4498161e0ec6d17b55b56/src/contractor.js#L491
73pub(crate) const MINIMUM_SUPPORTED_PGBOSS_APP_VERSION: u8 = 23;
74pub(crate) const CURRENT_PGBOSS_APP_VERSION: u8 = 23;
75
76#[derive(Debug, Clone, Default, FromRow)]
77pub(crate) struct App {
78    pub(crate) version: i32,
79    pub(crate) maintained_on: Option<DateTime<Utc>>,
80    pub(crate) cron_on: Option<DateTime<Utc>>,
81}