Skip to main content

FileStore

Struct FileStore 

Source
pub struct FileStore { /* private fields */ }
Expand description

A durable first-in first-out queue backed by one file per record.

Each append writes a record to its own sequence-numbered file, flushes it to disk, and atomically renames it into place, so a power loss mid-write leaves the queue consistent: a partially written record is never visible, and open clears what one left behind. On Linux and other Unix systems the directory is synced after the rename as well, so an append that returned is on disk. On Windows the directory entry is left to the file system, so an append that returned just before a power cut can be missing afterwards, though never half written. pop reads and deletes the oldest record.

Delivery is at-least-once: if the process stops between reading a record and deleting it, the next open returns that record again, so consumers must tolerate the occasional redelivery.

§Examples

use pamoja_core::Store;
use pamoja_sync::FileStore;

let mut store = FileStore::open("/var/lib/pamoja/outbox")?;
store.append(b"reading").await?;
if let Some(record) = store.pop().await? {
    // forward `record` over a transport, then it is gone from the queue
    let _ = record;
}

Implementations§

Source§

impl FileStore

Source

pub fn open(dir: impl AsRef<Path>) -> Result<Self>

Opens a store rooted at dir, creating the directory if needed.

Records left in the directory by a previous run are adopted in sequence order, so the queue resumes where it left off, and a record a power cut interrupted mid-write is deleted.

§Arguments
  • dir - the directory that holds the queue’s record files.
§Returns

A store with no limit on how many records it holds, ready to append and drain records.

§Errors

Returns Error::Io if the directory cannot be created or scanned, or an interrupted record cannot be deleted.

Source

pub fn open_with_capacity( dir: impl AsRef<Path>, capacity: usize, ) -> Result<Self>

Opens a store rooted at dir that holds at most capacity records.

An append that would take the store past capacity is refused rather than written, which on a device writing to an SD card is what keeps a long outage from filling the card. A store reopened with more records than capacity keeps them all and refuses appends until it is drained below it.

§Arguments
  • dir - the directory that holds the queue’s record files.
  • capacity - the most records the store holds.
§Returns

A bounded store, ready to append and drain records.

§Errors

As for open.

Trait Implementations§

Source§

impl Store for FileStore

Source§

async fn append(&mut self, record: &[u8]) -> Result<()>

Appends a record to the back of the queue. Read more
Source§

async fn peek(&self) -> Result<Option<Vec<u8>>>

Returns the oldest record without removing it. Read more
Source§

async fn pop(&mut self) -> Result<Option<Vec<u8>>>

Removes and returns the oldest record in the queue. Read more
Source§

async fn len(&self) -> Result<usize>

Returns the number of records currently buffered. Read more
§

fn append_text( &mut self, text: &str, ) -> impl Future<Output = Result<(), Error>> + Send

Appends text to the back of the queue: a reading or a line written out. Read more
§

fn peek_text( &self, ) -> impl Future<Output = Result<Option<String>, Error>> + Send
where Self: Sync,

Returns the oldest record as text, without removing it. Read more
§

fn pop_text( &mut self, ) -> impl Future<Output = Result<Option<String>, Error>> + Send
where Self: Send,

Removes and returns the oldest record as text. Read more
§

fn is_empty(&self) -> impl Future<Output = Result<bool, Error>> + Send
where Self: Sync,

Returns whether the queue currently holds no records. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.