pub mod contract;
mod memory;
pub use memory::{InMemoryNotifier, InMemoryQueueStore};
use crate::queue::QueuedMessage;
pub const STALE_INFLIGHT_SECS: i64 = 600;
#[derive(Debug, thiserror::Error)]
pub enum StoreError {
#[error("store backend: {0}")]
Backend(String),
}
#[async_trait::async_trait]
pub trait QueueStore: Send + Sync {
#[allow(clippy::too_many_arguments)]
async fn enqueue(
&self,
sender: &str,
recipient: &str,
domain: &str,
message_data: &[u8],
message_id: Option<&str>,
now: i64,
is_forwarded: bool,
) -> Result<i64, StoreError>;
#[allow(clippy::too_many_arguments)]
async fn enqueue_scheduled(
&self,
sender: &str,
recipient: &str,
domain: &str,
message_data: &[u8],
message_id: Option<&str>,
created_at: i64,
scheduled_at: i64,
) -> Result<i64, StoreError>;
async fn claim_for_delivery(
&self,
now: i64,
limit: u32,
) -> Result<Vec<QueuedMessage>, StoreError>;
async fn recover_stale_inflight(&self, now: i64) -> Result<u64, StoreError>;
async fn mark_delivered(&self, id: i64, now: i64) -> Result<(), StoreError>;
async fn mark_failed(
&self,
id: i64,
error: &str,
next_retry: i64,
now: i64,
) -> Result<(), StoreError>;
async fn mark_bounced(&self, id: i64, error: &str, now: i64) -> Result<(), StoreError>;
async fn get_message(&self, id: i64) -> Result<Option<QueuedMessage>, StoreError>;
async fn queue_stats(&self) -> Result<Vec<(String, i64)>, StoreError>;
async fn list_recent(&self, limit: i32) -> Result<Vec<QueuedMessage>, StoreError>;
async fn cancel_pending(&self, id: i64) -> Result<bool, StoreError>;
async fn cancel_pending_by_message_id(
&self,
message_id: &str,
sender: &str,
) -> Result<bool, StoreError>;
async fn retry_message(&self, id: i64, now: i64) -> Result<bool, StoreError>;
async fn reschedule_pending(
&self,
id: i64,
scheduled_at: i64,
now: i64,
) -> Result<bool, StoreError>;
async fn is_suppressed(&self, email: &str) -> Result<bool, StoreError>;
async fn add_suppression(
&self,
email: &str,
reason: &str,
smtp_code: Option<i32>,
) -> Result<(), StoreError>;
async fn remove_suppression(&self, email: &str) -> Result<bool, StoreError>;
async fn list_suppressions(
&self,
limit: i64,
) -> Result<Vec<(String, String, Option<i32>, i64)>, StoreError>;
}
#[async_trait::async_trait]
pub trait Notifier: Send + Sync {
async fn notify(&self);
async fn wait(&self);
}
pub struct NoopNotifier;
#[async_trait::async_trait]
impl Notifier for NoopNotifier {
async fn notify(&self) {}
async fn wait(&self) {
std::future::pending::<()>().await;
}
}