use super::{
Budget, Checkpoint, CheckpointError, CheckpointId, ClaimedWorkflow, LeaseDuration, SystemTime,
UNIX_EPOCH, Usage, WorkerId, WorkflowBudgetAuditCursor, WorkflowBudgetAuditEvent,
WorkflowBudgetAuditLimit, WorkflowBudgetAuditProjectionId, WorkflowBudgetAuditProjectionLease,
WorkflowBudgetReservationOutcome, WorkflowCancelOutcome, WorkflowCheckpointHistoryLimit,
WorkflowCheckpointRevision, WorkflowDisposition, WorkflowForkCommand, WorkflowForkOutcome,
WorkflowInterruptCommand, WorkflowInterruptDecisionOutcome, WorkflowLease, WorkflowSignal,
WorkflowSignalId, WorkflowSignalOutcome, WorkflowSignalRetention, WorkflowSignalSnapshot,
WorkflowStoreError, WorkflowStoreFuture, WorkflowTask, WorkflowTaskCleanupLease,
WorkflowTaskCleanupLimit, WorkflowTaskRetention, WorkflowTaskSnapshot, WorkflowTaskTombstone,
WorkflowTaskTombstoneCursor, WorkflowTaskTombstoneLimit, WorkflowTenantBudgetPolicy,
WorkflowTenantBudgetSnapshot, WorkflowTenantId, WorkflowTenantListLimit, WorkflowTenantPolicy,
};
pub trait WorkflowStore: Send + Sync {
fn set_tenant_policy(
&self,
tenant_id: WorkflowTenantId,
policy: WorkflowTenantPolicy,
) -> WorkflowStoreFuture<'_, Result<(), WorkflowStoreError>>;
fn set_tenant_budget_policy(
&self,
tenant_id: WorkflowTenantId,
policy: WorkflowTenantBudgetPolicy,
) -> WorkflowStoreFuture<'_, Result<(), WorkflowStoreError>>;
fn list_tenant_budgets(
&self,
after: Option<WorkflowTenantId>,
limit: WorkflowTenantListLimit,
) -> WorkflowStoreFuture<'_, Result<Vec<WorkflowTenantId>, WorkflowStoreError>>;
fn inspect_tenant_budget(
&self,
tenant_id: WorkflowTenantId,
) -> WorkflowStoreFuture<'_, Result<WorkflowTenantBudgetSnapshot, WorkflowStoreError>>;
fn list_tenant_budget_audit(
&self,
tenant_id: WorkflowTenantId,
after: Option<WorkflowBudgetAuditCursor>,
limit: WorkflowBudgetAuditLimit,
) -> WorkflowStoreFuture<'_, Result<Vec<WorkflowBudgetAuditEvent>, WorkflowStoreError>>;
fn compact_tenant_budget_audit(
&self,
tenant_id: WorkflowTenantId,
through: WorkflowBudgetAuditCursor,
) -> WorkflowStoreFuture<'_, Result<u64, WorkflowStoreError>>;
fn load_or_create_tenant_budget_audit_projection(
&self,
tenant_id: WorkflowTenantId,
projection_id: WorkflowBudgetAuditProjectionId,
) -> WorkflowStoreFuture<'_, Result<WorkflowBudgetAuditCursor, WorkflowStoreError>>;
fn advance_tenant_budget_audit_projection(
&self,
tenant_id: WorkflowTenantId,
projection_id: WorkflowBudgetAuditProjectionId,
expected: WorkflowBudgetAuditCursor,
next: WorkflowBudgetAuditCursor,
) -> WorkflowStoreFuture<'_, Result<bool, WorkflowStoreError>>;
fn claim_tenant_budget_audit_projection(
&self,
tenant_id: WorkflowTenantId,
projection_id: WorkflowBudgetAuditProjectionId,
owner: WorkerId,
lease: LeaseDuration,
) -> WorkflowStoreFuture<
'_,
Result<Option<WorkflowBudgetAuditProjectionLease>, WorkflowStoreError>,
>;
fn heartbeat_tenant_budget_audit_projection(
&self,
lease: WorkflowBudgetAuditProjectionLease,
extension: LeaseDuration,
) -> WorkflowStoreFuture<'_, Result<WorkflowBudgetAuditProjectionLease, WorkflowStoreError>>;
fn advance_tenant_budget_audit_projection_lease(
&self,
lease: WorkflowBudgetAuditProjectionLease,
next: WorkflowBudgetAuditCursor,
) -> WorkflowStoreFuture<'_, Result<WorkflowBudgetAuditProjectionLease, WorkflowStoreError>>;
fn release_tenant_budget_audit_projection(
&self,
lease: WorkflowBudgetAuditProjectionLease,
) -> WorkflowStoreFuture<'_, Result<(), WorkflowStoreError>>;
fn reserve_budget(
&self,
lease: WorkflowLease,
workflow_limit: Budget,
baseline: Usage,
) -> WorkflowStoreFuture<'_, Result<WorkflowBudgetReservationOutcome, WorkflowStoreError>>;
fn settle_budget(
&self,
lease: WorkflowLease,
cumulative: Usage,
) -> WorkflowStoreFuture<'_, Result<(), WorkflowStoreError>>;
fn enqueue(
&self,
task: WorkflowTask,
) -> WorkflowStoreFuture<'_, Result<(), WorkflowStoreError>>;
fn claim(
&self,
worker: WorkerId,
lease: LeaseDuration,
) -> WorkflowStoreFuture<'_, Result<Option<ClaimedWorkflow>, WorkflowStoreError>>;
fn heartbeat(
&self,
lease: WorkflowLease,
extension: LeaseDuration,
) -> WorkflowStoreFuture<'_, Result<WorkflowLease, WorkflowStoreError>>;
fn finish(
&self,
lease: WorkflowLease,
disposition: WorkflowDisposition,
) -> WorkflowStoreFuture<'_, Result<(), WorkflowStoreError>>;
fn publish_signal(
&self,
tenant_id: WorkflowTenantId,
signal: WorkflowSignal,
) -> WorkflowStoreFuture<'_, Result<WorkflowSignalOutcome, WorkflowStoreError>>;
fn decide_interrupt(
&self,
tenant_id: WorkflowTenantId,
command: WorkflowInterruptCommand,
) -> WorkflowStoreFuture<'_, Result<WorkflowInterruptDecisionOutcome, WorkflowStoreError>> {
Box::pin(async move {
let signal = command
.into_signal()
.map_err(|error| WorkflowStoreError::invalid_input(error.to_string()))?;
self.publish_signal(tenant_id, signal).await.map(Into::into)
})
}
fn cancel(
&self,
tenant_id: WorkflowTenantId,
checkpoint_id: CheckpointId,
) -> WorkflowStoreFuture<'_, Result<WorkflowCancelOutcome, WorkflowStoreError>>;
fn inspect_signal(
&self,
tenant_id: WorkflowTenantId,
signal_id: WorkflowSignalId,
) -> WorkflowStoreFuture<'_, Result<WorkflowSignalSnapshot, WorkflowStoreError>>;
fn compact_signals(
&self,
tenant_id: WorkflowTenantId,
retention: WorkflowSignalRetention,
) -> WorkflowStoreFuture<'_, Result<u64, WorkflowStoreError>>;
fn inspect(
&self,
tenant_id: WorkflowTenantId,
checkpoint_id: CheckpointId,
) -> WorkflowStoreFuture<'_, Result<WorkflowTaskSnapshot, WorkflowStoreError>>;
fn list_checkpoint_history(
&self,
tenant_id: WorkflowTenantId,
checkpoint_id: CheckpointId,
after_revision: Option<u64>,
limit: WorkflowCheckpointHistoryLimit,
) -> WorkflowStoreFuture<'_, Result<Vec<WorkflowCheckpointRevision>, WorkflowStoreError>>;
fn load_checkpoint_revision(
&self,
tenant_id: WorkflowTenantId,
checkpoint_id: CheckpointId,
revision: u64,
) -> WorkflowStoreFuture<'_, Result<WorkflowCheckpointRevision, WorkflowStoreError>>;
fn fork_workflow(
&self,
tenant_id: WorkflowTenantId,
command: WorkflowForkCommand,
) -> WorkflowStoreFuture<'_, Result<WorkflowForkOutcome, WorkflowStoreError>>;
fn load_checkpoint(
&self,
lease: WorkflowLease,
) -> WorkflowStoreFuture<'_, Result<Checkpoint, CheckpointError>>;
fn compare_and_swap_checkpoint(
&self,
lease: WorkflowLease,
checkpoint: Checkpoint,
expected_revision: Option<u64>,
) -> WorkflowStoreFuture<'_, Result<(), CheckpointError>>;
}
pub trait WorkflowTaskRetentionStore: WorkflowStore {
fn list_task_cleanup_tenants(
&self,
after: Option<WorkflowTenantId>,
limit: WorkflowTenantListLimit,
) -> WorkflowStoreFuture<'_, Result<Vec<WorkflowTenantId>, WorkflowStoreError>>;
fn claim_task_cleanup(
&self,
tenant_id: WorkflowTenantId,
owner: WorkerId,
lease: LeaseDuration,
) -> WorkflowStoreFuture<'_, Result<Option<WorkflowTaskCleanupLease>, WorkflowStoreError>>;
fn compact_terminal_tasks(
&self,
lease: WorkflowTaskCleanupLease,
retention: WorkflowTaskRetention,
limit: WorkflowTaskCleanupLimit,
) -> WorkflowStoreFuture<'_, Result<Vec<WorkflowTaskTombstone>, WorkflowStoreError>>;
fn heartbeat_task_cleanup(
&self,
lease: WorkflowTaskCleanupLease,
extension: LeaseDuration,
) -> WorkflowStoreFuture<'_, Result<WorkflowTaskCleanupLease, WorkflowStoreError>>;
fn list_task_tombstones(
&self,
tenant_id: WorkflowTenantId,
after: Option<WorkflowTaskTombstoneCursor>,
limit: WorkflowTaskTombstoneLimit,
) -> WorkflowStoreFuture<'_, Result<Vec<WorkflowTaskTombstone>, WorkflowStoreError>>;
fn release_task_cleanup(
&self,
lease: WorkflowTaskCleanupLease,
) -> WorkflowStoreFuture<'_, Result<(), WorkflowStoreError>>;
}
pub trait WorkflowClock: Send + Sync {
fn now_ms(&self) -> u64;
}
#[derive(Clone, Copy, Debug, Default)]
pub struct SystemWorkflowClock;
impl WorkflowClock for SystemWorkflowClock {
fn now_ms(&self) -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map_or(0, |duration| {
u64::try_from(duration.as_millis()).unwrap_or(u64::MAX)
})
}
}