Skip to main content

persistent_queue/
lib.rs

1//! A durable, at-least-once MPSC queue backed by in-memory and durable backends.
2//!
3//! Items are written to a [`Store`] and survive process and machine crashes.
4//! Delivery is at-least-once: an item is removed only once the consumer acks it,
5//! so a crash between handling and ack redelivers it. The core is synchronous and
6//! runtime-agnostic.
7//!
8//! ```
9//! use persistent_queue::{Builder, MemStore};
10//!
11//! let (tx, rx) = Builder::new(MemStore::new()).capacity(1024).open().unwrap();
12//! tx.push(b"job").unwrap();
13//! let item = rx.reserve().unwrap().unwrap();
14//! assert_eq!(&*item, b"job");
15//! item.ack().unwrap();
16//! ```
17//!
18//! For typed messages, [`Builder::open_typed`] wraps the queue with a [`Codec`] that
19//! encodes on push and decodes on reserve (serde and bincode behind the `serde`
20//! feature). With the `tokio` feature, [`Builder::open_async`] gives async
21//! producer/consumer handles that run store I/O on tokio's blocking pool and wait
22//! (for capacity, or the next item) asynchronously.
23//!
24//! See `DESIGN.md` for the on-disk layout, crash recovery, and durability model.
25#![warn(missing_docs)]
26
27#[cfg(feature = "tokio")]
28mod async_queue;
29mod codec;
30mod error;
31mod queue;
32mod store;
33mod sync;
34mod typed;
35
36pub use codec::{Codec, CodecError};
37pub use error::{OpenError, PushError, TryPushError};
38pub use queue::{Builder, Consumer, Durability, Ends, Producer, Reserved};
39pub use store::{KeyValue, MemStore, Op, Store};
40pub use typed::{
41    ReserveError, TypedConsumer, TypedEnds, TypedProducer, TypedPushError, TypedReserved,
42};
43
44#[cfg(feature = "tokio")]
45pub use async_queue::{AsyncConsumer, AsyncEnds, AsyncProducer, AsyncReserved};
46#[cfg(feature = "serde")]
47pub use codec::Bincode;
48
49#[cfg(feature = "redb")]
50pub use store::RedbStore;
51#[cfg(feature = "rocksdb")]
52pub use store::RocksStore;
53#[cfg(feature = "sled")]
54pub use store::SledStore;