use dovecote::{
ClaimedEvent, EnqueueOutcome, FinalizeOutcome, ImportOutcome, ImportedDeliveryState, NewEvent,
TenantId,
};
use sqlx::{Postgres, Transaction};
use time::OffsetDateTime;
use crate::{
ClaimError, EnqueueError, FinalizeError, ImportError, MutationError, PageError, SnapshotPager,
enqueue, finalize, import, lifecycle, page, rls,
};
#[derive(Clone)]
pub struct TenantDovecote {
pool: sqlx::PgPool,
tenant_id: TenantId,
}
impl TenantDovecote {
pub(crate) fn new(pool: sqlx::PgPool, tenant_id: TenantId) -> Self {
Self { pool, tenant_id }
}
pub fn tenant_id(&self) -> &TenantId {
&self.tenant_id
}
pub fn pool(&self) -> &sqlx::PgPool {
&self.pool
}
pub async fn bind_tenant<'c>(
&self,
transaction: &mut Transaction<'c, Postgres>,
) -> Result<(), sqlx::Error> {
rls::bind_tenant(transaction, &self.tenant_id).await
}
pub async fn enqueue<'c>(
&self,
transaction: &mut Transaction<'c, Postgres>,
event: NewEvent,
) -> Result<EnqueueOutcome, EnqueueError> {
self.bind_tenant(transaction)
.await
.map_err(|source| EnqueueError::sql("bind tenant", source))?;
enqueue::enqueue_for_scope(transaction, &self.tenant_id, event).await
}
pub async fn import_for_migration<'c>(
&self,
transaction: &mut Transaction<'c, Postgres>,
event: NewEvent,
state: ImportedDeliveryState,
) -> Result<ImportOutcome, ImportError> {
self.bind_tenant(transaction)
.await
.map_err(|source| ImportError::sql("bind tenant", source))?;
import::import_for_scope(transaction, &self.tenant_id, event, state).await
}
pub async fn finalize_pending_delivery_for_migration<'c>(
&self,
transaction: &mut Transaction<'c, Postgres>,
row_id: dovecote::RowId,
delivered_at: OffsetDateTime,
) -> Result<FinalizeOutcome, FinalizeError> {
self.bind_tenant(transaction)
.await
.map_err(|source| FinalizeError::sql("bind tenant", source))?;
finalize::finalize_for_scope(transaction, &self.tenant_id, row_id, delivered_at).await
}
pub async fn page(
&self,
after_row_id: Option<dovecote::RowId>,
limit: dovecote::Limit,
) -> Result<Vec<dovecote::PagedEvent>, PageError> {
page::page_for_scope(&self.pool, Some(&self.tenant_id), after_row_id, limit).await
}
pub async fn begin_snapshot(&self) -> Result<SnapshotPager, PageError> {
page::begin_snapshot_for_scope(&self.pool, Some(&self.tenant_id)).await
}
pub async fn claim(
&self,
worker: dovecote::WorkerId,
lease_for: dovecote::Lease,
limit: dovecote::Limit,
) -> Result<Vec<ClaimedEvent>, ClaimError> {
lifecycle::claim_for_scope(&self.pool, Some(&self.tenant_id), worker, lease_for, limit)
.await
}
pub async fn renew(
&self,
row_id: dovecote::RowId,
claim_token: &dovecote::ClaimToken,
lease_for: dovecote::Lease,
) -> Result<(), MutationError> {
lifecycle::renew_for_scope(
&self.pool,
Some(&self.tenant_id),
row_id,
claim_token,
lease_for,
)
.await
}
pub async fn ack(
&self,
row_id: dovecote::RowId,
claim_token: &dovecote::ClaimToken,
) -> Result<(), MutationError> {
lifecycle::ack_for_scope(&self.pool, Some(&self.tenant_id), row_id, claim_token).await
}
pub async fn retry(
&self,
row_id: dovecote::RowId,
claim_token: &dovecote::ClaimToken,
failure: &dovecote::Failure,
backoff: dovecote::Delay,
) -> Result<(), MutationError> {
lifecycle::retry_for_scope(
&self.pool,
Some(&self.tenant_id),
row_id,
claim_token,
failure,
backoff,
)
.await
}
pub async fn release(
&self,
row_id: dovecote::RowId,
claim_token: &dovecote::ClaimToken,
delay: dovecote::Delay,
) -> Result<(), MutationError> {
lifecycle::release_for_scope(
&self.pool,
Some(&self.tenant_id),
row_id,
claim_token,
delay,
)
.await
}
pub async fn quarantine(
&self,
row_id: dovecote::RowId,
claim_token: &dovecote::ClaimToken,
reason: &dovecote::QuarantineReason,
) -> Result<(), MutationError> {
lifecycle::quarantine_for_scope(
&self.pool,
Some(&self.tenant_id),
row_id,
claim_token,
reason,
)
.await
}
}
#[derive(Clone)]
pub struct AdminDovecote {
pool: sqlx::PgPool,
}
impl AdminDovecote {
pub(crate) fn new(pool: sqlx::PgPool) -> Self {
Self { pool }
}
pub fn pool(&self) -> &sqlx::PgPool {
&self.pool
}
pub async fn enqueue<'c>(
&self,
transaction: &mut Transaction<'c, Postgres>,
tenant_id: TenantId,
event: NewEvent,
) -> Result<EnqueueOutcome, EnqueueError> {
enqueue::enqueue_for_scope(transaction, &tenant_id, event).await
}
pub async fn import_for_migration<'c>(
&self,
transaction: &mut Transaction<'c, Postgres>,
tenant_id: TenantId,
event: NewEvent,
state: ImportedDeliveryState,
) -> Result<ImportOutcome, ImportError> {
import::import_for_scope(transaction, &tenant_id, event, state).await
}
pub async fn finalize_pending_delivery_for_migration<'c>(
&self,
transaction: &mut Transaction<'c, Postgres>,
tenant_id: TenantId,
row_id: dovecote::RowId,
delivered_at: OffsetDateTime,
) -> Result<FinalizeOutcome, FinalizeError> {
finalize::finalize_for_scope(transaction, &tenant_id, row_id, delivered_at).await
}
pub async fn page(
&self,
after_row_id: Option<dovecote::RowId>,
limit: dovecote::Limit,
) -> Result<Vec<dovecote::PagedEvent>, PageError> {
page::page_for_scope(&self.pool, None, after_row_id, limit).await
}
pub async fn begin_snapshot(&self) -> Result<SnapshotPager, PageError> {
page::begin_snapshot_for_scope(&self.pool, None).await
}
pub async fn claim(
&self,
worker: dovecote::WorkerId,
lease_for: dovecote::Lease,
limit: dovecote::Limit,
) -> Result<Vec<ClaimedEvent>, ClaimError> {
lifecycle::claim_for_scope(&self.pool, None, worker, lease_for, limit).await
}
pub async fn renew(
&self,
tenant_id: TenantId,
row_id: dovecote::RowId,
claim_token: &dovecote::ClaimToken,
lease_for: dovecote::Lease,
) -> Result<(), MutationError> {
lifecycle::renew_for_scope(&self.pool, Some(&tenant_id), row_id, claim_token, lease_for)
.await
}
pub async fn ack(
&self,
tenant_id: TenantId,
row_id: dovecote::RowId,
claim_token: &dovecote::ClaimToken,
) -> Result<(), MutationError> {
lifecycle::ack_for_scope(&self.pool, Some(&tenant_id), row_id, claim_token).await
}
pub async fn retry(
&self,
tenant_id: TenantId,
row_id: dovecote::RowId,
claim_token: &dovecote::ClaimToken,
failure: &dovecote::Failure,
backoff: dovecote::Delay,
) -> Result<(), MutationError> {
lifecycle::retry_for_scope(
&self.pool,
Some(&tenant_id),
row_id,
claim_token,
failure,
backoff,
)
.await
}
pub async fn release(
&self,
tenant_id: TenantId,
row_id: dovecote::RowId,
claim_token: &dovecote::ClaimToken,
delay: dovecote::Delay,
) -> Result<(), MutationError> {
lifecycle::release_for_scope(&self.pool, Some(&tenant_id), row_id, claim_token, delay).await
}
pub async fn quarantine(
&self,
tenant_id: TenantId,
row_id: dovecote::RowId,
claim_token: &dovecote::ClaimToken,
reason: &dovecote::QuarantineReason,
) -> Result<(), MutationError> {
lifecycle::quarantine_for_scope(&self.pool, Some(&tenant_id), row_id, claim_token, reason)
.await
}
}