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§
Sourcefn 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<'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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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_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.
Sourcefn 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_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.
Sourcefn 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_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.
Sourcefn 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 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).
Sourcefn 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 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.
Sourcefn 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 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)].
Sourcefn 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 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.
Sourcefn 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<'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.
Sourcefn 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 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).
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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,
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".