Skip to main content

QueueStore

Trait QueueStore 

Source
pub trait QueueStore: Send + Sync {
Show 18 methods // Required methods fn enqueue<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>( &'life0 self, sender: &'life1 str, recipient: &'life2 str, domain: &'life3 str, message_data: &'life4 [u8], message_id: Option<&'life5 str>, now: i64, is_forwarded: bool, ) -> Pin<Box<dyn Future<Output = Result<i64, StoreError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait, 'life5: 'async_trait; fn enqueue_scheduled<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>( &'life0 self, sender: &'life1 str, recipient: &'life2 str, domain: &'life3 str, message_data: &'life4 [u8], message_id: Option<&'life5 str>, created_at: i64, scheduled_at: i64, ) -> Pin<Box<dyn Future<Output = Result<i64, StoreError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait, 'life5: 'async_trait; fn dequeue<'life0, 'async_trait>( &'life0 self, now: i64, limit: u32, ) -> Pin<Box<dyn Future<Output = Result<Vec<QueuedMessage>, StoreError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn recover_stale_inflight<'life0, 'async_trait>( &'life0 self, now: i64, ) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn mark_inflight<'life0, 'async_trait>( &'life0 self, id: i64, now: i64, ) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn mark_delivered<'life0, 'async_trait>( &'life0 self, id: i64, now: i64, ) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn mark_failed<'life0, 'life1, 'async_trait>( &'life0 self, id: i64, error: &'life1 str, next_retry: i64, now: i64, ) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn mark_bounced<'life0, 'life1, 'async_trait>( &'life0 self, id: i64, error: &'life1 str, now: i64, ) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn get_message<'life0, 'async_trait>( &'life0 self, id: i64, ) -> Pin<Box<dyn Future<Output = Result<Option<QueuedMessage>, StoreError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn queue_stats<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<(String, i64)>, StoreError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn list_recent<'life0, 'async_trait>( &'life0 self, limit: i32, ) -> Pin<Box<dyn Future<Output = Result<Vec<QueuedMessage>, StoreError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn cancel_pending<'life0, 'async_trait>( &'life0 self, id: i64, ) -> Pin<Box<dyn Future<Output = Result<bool, StoreError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn cancel_pending_by_message_id<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, message_id: &'life1 str, sender: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<bool, StoreError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn retry_message<'life0, 'async_trait>( &'life0 self, id: i64, now: i64, ) -> Pin<Box<dyn Future<Output = Result<bool, StoreError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn is_suppressed<'life0, 'life1, 'async_trait>( &'life0 self, email: &'life1 str, ) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn add_suppression<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, email: &'life1 str, reason: &'life2 str, smtp_code: Option<i32>, ) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn remove_suppression<'life0, 'life1, 'async_trait>( &'life0 self, email: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<bool, StoreError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn list_suppressions<'life0, 'async_trait>( &'life0 self, limit: i64, ) -> Pin<Box<dyn Future<Output = Result<Vec<(String, String, Option<i32>, i64)>, StoreError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait;
}
Expand description

The persistent store the outbound queue lives in.

enqueue* is called by the SMTP submission path. dequeue + mark_* is called by a delivery worker. list_recent / queue_stats / cancel_* / retry_message is called by admin / management code.

Implementations should be ACID-safe for the lifecycle transitions pending → inflight → {delivered, failed, bounced} so a crashed worker can’t lose or duplicate-deliver a message.

Required Methods§

Source

fn enqueue<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>( &'life0 self, sender: &'life1 str, recipient: &'life2 str, domain: &'life3 str, message_data: &'life4 [u8], message_id: Option<&'life5 str>, now: i64, is_forwarded: bool, ) -> Pin<Box<dyn Future<Output = Result<i64, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait, 'life5: 'async_trait,

Insert a new pending message. Returns the assigned id.

Source

fn enqueue_scheduled<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>( &'life0 self, sender: &'life1 str, recipient: &'life2 str, domain: &'life3 str, message_data: &'life4 [u8], message_id: Option<&'life5 str>, created_at: i64, scheduled_at: i64, ) -> Pin<Box<dyn Future<Output = Result<i64, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait, 'life5: 'async_trait,

Insert a message scheduled to deliver at scheduled_at.

Source

fn dequeue<'life0, 'async_trait>( &'life0 self, now: i64, limit: u32, ) -> Pin<Box<dyn Future<Output = Result<Vec<QueuedMessage>, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Fetch up to limit pending messages whose next_retry is <= now.

Source

fn recover_stale_inflight<'life0, 'async_trait>( &'life0 self, now: i64, ) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Reset inflight messages older than ~10 minutes back to pending (crash-recovery). Returns rows affected.

Source

fn mark_inflight<'life0, 'async_trait>( &'life0 self, id: i64, now: i64, ) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Mark a message as currently being delivered.

Source

fn mark_delivered<'life0, 'async_trait>( &'life0 self, id: i64, now: i64, ) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Mark a message as delivered.

Source

fn mark_failed<'life0, 'life1, 'async_trait>( &'life0 self, id: i64, error: &'life1 str, next_retry: i64, now: i64, ) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Mark a delivery attempt as failed; the message goes back to pending with an incremented attempts and a next_retry of next_retry.

Source

fn mark_bounced<'life0, 'life1, 'async_trait>( &'life0 self, id: i64, error: &'life1 str, now: i64, ) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Mark a message as permanently bounced (no more retries).

Source

fn get_message<'life0, 'async_trait>( &'life0 self, id: i64, ) -> Pin<Box<dyn Future<Output = Result<Option<QueuedMessage>, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Fetch a single message by id, or None if it has been purged.

Source

fn queue_stats<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<(String, i64)>, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Group counts by status — e.g. [("pending", 12), ("inflight", 2)].

Source

fn list_recent<'life0, 'async_trait>( &'life0 self, limit: i32, ) -> Pin<Box<dyn Future<Output = Result<Vec<QueuedMessage>, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Recently-created entries, newest first, for admin UIs.

Source

fn cancel_pending<'life0, 'async_trait>( &'life0 self, id: i64, ) -> Pin<Box<dyn Future<Output = Result<bool, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Delete a single pending message. Returns true if a row was removed.

Source

fn cancel_pending_by_message_id<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, message_id: &'life1 str, sender: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<bool, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Delete a single pending message identified by RFC 5322 Message-ID and sender (so a user can only cancel their own undelivered messages).

Source

fn retry_message<'life0, 'async_trait>( &'life0 self, id: i64, now: i64, ) -> Pin<Box<dyn Future<Output = Result<bool, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Reset a bounced / failed message to pending for another try.

Source

fn is_suppressed<'life0, 'life1, 'async_trait>( &'life0 self, email: &'life1 str, ) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

true if the recipient is in the hard-bounce suppression list.

Source

fn add_suppression<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, email: &'life1 str, reason: &'life2 str, smtp_code: Option<i32>, ) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Add (or update) a recipient on the suppression list.

Source

fn remove_suppression<'life0, 'life1, 'async_trait>( &'life0 self, email: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<bool, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Remove a recipient from the suppression list. Returns true if a row was removed.

Source

fn list_suppressions<'life0, 'async_trait>( &'life0 self, limit: i64, ) -> Pin<Box<dyn Future<Output = Result<Vec<(String, String, Option<i32>, i64)>, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

(email, reason, smtp_code, created_at_epoch) tuples, newest first.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§