pub struct PostgresBackend { /* private fields */ }Implementations§
Source§impl PostgresBackend
impl PostgresBackend
Sourcepub async fn connect(
config: BackendConfig,
) -> Result<Arc<dyn EngineBackend>, EngineError>
pub async fn connect( config: BackendConfig, ) -> Result<Arc<dyn EngineBackend>, EngineError>
Dial Postgres with BackendConfig and return the backend as
Arc<dyn EngineBackend>. Modeled on
[ff_backend_valkey::ValkeyBackend::connect] so ff-server /
SDK call sites can swap backends without changing the
constructor shape.
Wave 0: builds the pool and constructs the backend. Does
NOT run migrations (Q12 — operator out-of-band). Does NOT run
the schema-version check (Wave 3 adds the version const and
wires check_schema_version in). Does NOT start the LISTEN
task (Wave 4).
Returns EngineError::Unavailable when the config’s
connection arm is not Postgres.
Sourcepub fn from_pool(pool: PgPool, partition_config: PartitionConfig) -> Arc<Self> ⓘ
pub fn from_pool(pool: PgPool, partition_config: PartitionConfig) -> Arc<Self> ⓘ
Test / advanced constructor: build a PostgresBackend from an
already-constructed PgPool + explicit partition config. No
network I/O. Useful for integration tests against a shared
pool and for a future migration CLI that wants to reuse a pool
across migrate-run + smoke-check.
Sourcepub async fn connect_with_metrics(
config: BackendConfig,
partition_config: PartitionConfig,
metrics: Arc<Metrics>,
) -> Result<Arc<Self>, EngineError>
pub async fn connect_with_metrics( config: BackendConfig, partition_config: PartitionConfig, metrics: Arc<Metrics>, ) -> Result<Arc<Self>, EngineError>
RFC-017 Wave 8 Stage E1: dial Postgres with an explicit
PartitionConfig + shared ff_observability::Metrics.
Mirrors [ff_backend_valkey::ValkeyBackend::connect_with_metrics]
so ff-server::Server::start_with_metrics can wire the Postgres
branch without reaching into the pool builder directly.
Returns a concrete Arc<Self> rather than Arc<dyn EngineBackend>
so the caller can cast to the trait object after any additional
field installs (parallel to the Valkey path which calls
with_scheduler / with_stream_semaphore_permits before the
cast). Stage E1 does NOT run apply_migrations — schema
provisioning is an operator concern (matches the Wave 0 contract
on Self::connect).
Sourcepub fn with_scanners(self: &mut Arc<Self>, cfg: PostgresScannerConfig) -> bool
pub fn with_scanners(self: &mut Arc<Self>, cfg: PostgresScannerConfig) -> bool
RFC-017 Wave 8 Stage E3: spawn the six Postgres reconcilers as
background tick loops. Returns true if the scanner handle
was installed; false if the Arc<Self> has outstanding
clones (mirrors the Valkey with_* pattern). Callers must
invoke this before publishing the Arc<dyn EngineBackend> so
the underlying Arc::get_mut succeeds.
Sourcepub fn pool(&self) -> &PgPool
pub fn pool(&self) -> &PgPool
Accessor for the underlying PgPool. Stage E1 uses this so
ff-server::Server::start_with_metrics can run
apply_migrations on the same pool before handing the backend
out as Arc<dyn EngineBackend>.
Sourcepub async fn create_execution(
&self,
args: CreateExecutionArgs,
) -> Result<ExecutionId, EngineError>
pub async fn create_execution( &self, args: CreateExecutionArgs, ) -> Result<ExecutionId, EngineError>
Create one execution row (+ seed the lane registry if new).
RFC-017 Stage A: this inherent method is retained as a
thin wrapper around the module-level impl so existing in-tree
callers (ff-server request handlers, integration tests) keep
compiling. The trait-lifted entry point is
EngineBackend::create_execution below, which calls the
same impl. Return shape differs — inherent returns
ExecutionId, trait returns
CreateExecutionResult per RFC-017 §5 — so we cannot simply
replace the inherent method. A follow-up PR may deprecate
this inherent alongside the broader ingress shape alignment.
pub async fn create_flow( &self, args: &CreateFlowArgs, ) -> Result<CreateFlowResult, EngineError>
pub async fn add_execution_to_flow( &self, args: &AddExecutionToFlowArgs, ) -> Result<AddExecutionToFlowResult, EngineError>
pub async fn stage_dependency_edge( &self, args: &StageDependencyEdgeArgs, ) -> Result<StageDependencyEdgeResult, EngineError>
pub async fn apply_dependency_to_child( &self, args: &ApplyDependencyToChildArgs, ) -> Result<ApplyDependencyToChildResult, EngineError>
Trait Implementations§
Source§impl CompletionBackend for PostgresBackend
impl CompletionBackend for PostgresBackend
Source§fn subscribe_completions<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<CompletionStream, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn subscribe_completions<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<CompletionStream, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn subscribe_completions_filtered<'life0, 'life1, 'async_trait>(
&'life0 self,
filter: &'life1 ScannerFilter,
) -> Pin<Box<dyn Future<Output = Result<CompletionStream, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn subscribe_completions_filtered<'life0, 'life1, 'async_trait>(
&'life0 self,
filter: &'life1 ScannerFilter,
) -> Pin<Box<dyn Future<Output = Result<CompletionStream, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
ScannerFilter applied at the backend boundary (issue #122). Read moreSource§impl EngineBackend for PostgresBackend
impl EngineBackend for PostgresBackend
Source§fn create_execution<'life0, 'async_trait>(
&'life0 self,
args: CreateExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<CreateExecutionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn create_execution<'life0, 'async_trait>(
&'life0 self,
args: CreateExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<CreateExecutionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
RFC-017 Wave 8 Stage E1: lift the inherent
PostgresBackend::create_execution onto the trait so
ff-server’s migrated HTTP handler can dispatch to Postgres.
Post-insert the row is idempotent; the Postgres impl does not
distinguish Created from Duplicate at the helper level
(both paths commit and return the execution id), so we always
surface Created { public_state: Waiting } here. A follow-up
may lift the distinction if a consumer relies on it.
Source§fn capabilities(&self) -> Capabilities
fn capabilities(&self) -> Capabilities
RFC-018 Stage A: populate the Capabilities snapshot from the
static [postgres_supports_base] shape. The Postgres backend
landed through RFC-017 Stage E4 at v0.8.0; fields still false
correspond to Wave-9 follow-up work (cancel_flow_header,
ack_cancel_member, read-model, operator control, budget /
quota, list_pending_waitpoints). See
docs/POSTGRES_PARITY_MATRIX.md for the per-row breakdown.
Source§fn prepare<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<PrepareOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn prepare<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<PrepareOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Issue #281: no-op. Schema migrations are applied out-of-band
per rfcs/drafts/v0.7-migration-master.md §Q12 (operator runs
sqlx migrate run or the future ff-migrate CLI). Boot runs a
schema-version check at connect time
(crate::version::check_schema_version) and refuses to
start on mismatch, so by the time prepare() is callable
there is nothing further to do.
Source§fn claim_for_worker<'life0, 'async_trait>(
&'life0 self,
args: ClaimForWorkerArgs,
) -> Pin<Box<dyn Future<Output = Result<ClaimForWorkerOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn claim_for_worker<'life0, 'async_trait>(
&'life0 self,
args: ClaimForWorkerArgs,
) -> Pin<Box<dyn Future<Output = Result<ClaimForWorkerOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
RFC-017 Wave 8 Stage E3 (§4 row 9, §7): forward the claim to the
Postgres-native admission pipeline. Returns NoWork when no
eligible execution is admissible this scan cycle. Budget
breaches surface as NoWork (leaving the row eligible for a
retry by another worker); validation-class rejections
(malformed partition, unknown kid) surface as typed
EngineError variants mapped to the Server’s 400/503 arms.
Source§fn shutdown_prepare<'life0, 'async_trait>(
&'life0 self,
grace: Duration,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn shutdown_prepare<'life0, 'async_trait>(
&'life0 self,
grace: Duration,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
RFC-017 Wave 8 Stage E3: drain the scanner supervisor’s
reconciler tasks up to grace, then close the sqlx pool.
Matches the Valkey backend’s shutdown_prepare contract —
bounded best-effort drain, never returns an error.
Source§fn claim<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
lane: &'life1 LaneId,
capabilities: &'life2 CapabilitySet,
policy: ClaimPolicy,
) -> Pin<Box<dyn Future<Output = Result<Option<Handle>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn claim<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
lane: &'life1 LaneId,
capabilities: &'life2 CapabilitySet,
policy: ClaimPolicy,
) -> Pin<Box<dyn Future<Output = Result<Option<Handle>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Ok(None) when no work is currently
available; Err only on transport or input-validation faults.Source§fn renew<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
) -> Pin<Box<dyn Future<Output = Result<LeaseRenewal, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn renew<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
) -> Pin<Box<dyn Future<Output = Result<LeaseRenewal, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
State::StaleLease / State::LeaseExpired
when the lease has been stolen or timed out.Source§fn progress<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
percent: Option<u8>,
message: Option<String>,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn progress<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
percent: Option<u8>,
message: Option<String>,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn append_frame<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
frame: Frame,
) -> Pin<Box<dyn Future<Output = Result<AppendFrameOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn append_frame<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
frame: Frame,
) -> Pin<Box<dyn Future<Output = Result<AppendFrameOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn complete<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
payload: Option<Vec<u8>>,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn complete<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
payload: Option<Vec<u8>>,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
handle (round-4 M-D2) so callers
can retry under EngineError::Transport without losing the
cookie. Payload is Option<Vec<u8>> per the note above.Source§fn fail<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
reason: FailureReason,
classification: FailureClass,
) -> Pin<Box<dyn Future<Output = Result<FailOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn fail<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
reason: FailureReason,
classification: FailureClass,
) -> Pin<Box<dyn Future<Output = Result<FailOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
FailOutcome
so the caller learns whether a retry was scheduled.Source§fn cancel<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
reason: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn cancel<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
reason: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Source§fn suspend<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
args: SuspendArgs,
) -> Pin<Box<dyn Future<Output = Result<SuspendOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn suspend<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
args: SuspendArgs,
) -> Pin<Box<dyn Future<Output = Result<SuspendOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn suspend_by_triple<'life0, 'async_trait>(
&'life0 self,
exec_id: ExecutionId,
triple: LeaseFence,
args: SuspendArgs,
) -> Pin<Box<dyn Future<Output = Result<SuspendOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn suspend_by_triple<'life0, 'async_trait>(
&'life0 self,
exec_id: ExecutionId,
triple: LeaseFence,
args: SuspendArgs,
) -> Pin<Box<dyn Future<Output = Result<SuspendOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn create_waitpoint<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
waitpoint_key: &'life2 str,
expires_in: Duration,
) -> Pin<Box<dyn Future<Output = Result<PendingWaitpoint, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn create_waitpoint<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
waitpoint_key: &'life2 str,
expires_in: Duration,
) -> Pin<Box<dyn Future<Output = Result<PendingWaitpoint, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Source§fn read_waitpoint_token<'life0, 'life1, 'async_trait>(
&'life0 self,
partition: PartitionKey,
waitpoint_id: &'life1 WaitpointId,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn read_waitpoint_token<'life0, 'life1, 'async_trait>(
&'life0 self,
partition: PartitionKey,
waitpoint_id: &'life1 WaitpointId,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
(partition, waitpoint_id). Read moreSource§fn observe_signals<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
) -> Pin<Box<dyn Future<Output = Result<Vec<ResumeSignal>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn observe_signals<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
) -> Pin<Box<dyn Future<Output = Result<Vec<ResumeSignal>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn claim_from_resume_grant<'life0, 'async_trait>(
&'life0 self,
token: ResumeToken,
) -> Pin<Box<dyn Future<Output = Result<Option<Handle>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn claim_from_resume_grant<'life0, 'async_trait>(
&'life0 self,
token: ResumeToken,
) -> Pin<Box<dyn Future<Output = Result<Option<Handle>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
ResumeToken) to mint a
resumed-kind handle. Routes to ff_claim_resumed_execution on
Valkey / the epoch-bump reconciler on PG/SQLite. Returns
Ok(None) when the grant’s target execution is no longer
resumable (already reclaimed, terminal, etc.). Read moreSource§fn issue_reclaim_grant<'life0, 'async_trait>(
&'life0 self,
args: IssueReclaimGrantArgs,
) -> Pin<Box<dyn Future<Output = Result<IssueReclaimGrantOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn issue_reclaim_grant<'life0, 'async_trait>(
&'life0 self,
args: IssueReclaimGrantArgs,
) -> Pin<Box<dyn Future<Output = Result<IssueReclaimGrantOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
lease_expired_reclaimable or lease_revoked state to the
reclaim path; the returned IssueReclaimGrantOutcome::Granted
carries a crate::contracts::ReclaimGrant which is then fed
to Self::reclaim_execution to mint a fresh attempt. Read moreSource§fn reclaim_execution<'life0, 'async_trait>(
&'life0 self,
args: ReclaimExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<ReclaimExecutionOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn reclaim_execution<'life0, 'async_trait>(
&'life0 self,
args: ReclaimExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<ReclaimExecutionOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
crate::contracts::ReclaimGrant to mint a fresh
attempt for a previously lease-expired / lease-revoked
execution (RFC-024 §3.2). Creates a new attempt row, bumps the
execution’s lease_reclaim_count, and mints a
crate::backend::HandleKind::Reclaimed handle. Read moreSource§fn delay<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
delay_until: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn delay<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
delay_until: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
delay_until, releasing the lease.Source§fn wait_children<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn wait_children<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 Handle,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn describe_execution<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<Option<ExecutionSnapshot>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn describe_execution<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<Option<ExecutionSnapshot>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Ok(None) ⇒ no such execution.Source§fn read_execution_context<'life0, 'life1, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<ExecutionContext, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn read_execution_context<'life0, 'life1, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<ExecutionContext, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
(input_payload, execution_kind, tags) bundle used by the SDK worker when
assembling a ClaimedTask (see ff_sdk::ClaimedTask) after a
successful claim. Read moreSource§fn read_current_attempt_index<'life0, 'life1, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<AttemptIndex, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn read_current_attempt_index<'life0, 'life1, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<AttemptIndex, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn read_total_attempt_count<'life0, 'life1, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<AttemptIndex, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn read_total_attempt_count<'life0, 'life1, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<AttemptIndex, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn describe_flow<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 FlowId,
) -> Pin<Box<dyn Future<Output = Result<Option<FlowSnapshot>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn describe_flow<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 FlowId,
) -> Pin<Box<dyn Future<Output = Result<Option<FlowSnapshot>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Ok(None) ⇒ no such flow.Source§fn set_execution_tag<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
key: &'life2 str,
value: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn set_execution_tag<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
key: &'life2 str,
value: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
key MUST match
the reserved caller-namespace pattern ^[a-z][a-z0-9_]*\.[a-z0-9_][a-z0-9_.]*$ —
i.e. <caller>.<field> — or the call returns
EngineError::Validation { kind: ValidationKind::InvalidInput, .. }
with the offending key in detail. value is arbitrary UTF-8. Read moreSource§fn set_flow_tag<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
flow_id: &'life1 FlowId,
key: &'life2 str,
value: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn set_flow_tag<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
flow_id: &'life1 FlowId,
key: &'life2 str,
value: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self::set_execution_tag: key MUST match
^[a-z][a-z0-9_]*\.[a-z0-9_][a-z0-9_.]*$. Read moreSource§fn get_execution_tag<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
key: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn get_execution_tag<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
key: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Ok(None) when
the tag is absent or the execution row does not exist —
the two cases are not distinguished on the read path. Callers
that need to distinguish should call Self::describe_execution
first (an Ok(None) from that method proves the execution is
absent). This matches Valkey’s native HGET semantics and
keeps the read path at a single round-trip on every backend. Read moreSource§fn get_flow_tag<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
flow_id: &'life1 FlowId,
key: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn get_flow_tag<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
flow_id: &'life1 FlowId,
key: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Ok(None) when
the tag is absent or the flow row does not exist (same
collapse semantics as Self::get_execution_tag). Symmetry
partner — consumers like cairn read cairn.session_id off
flows for archival. Read moreSource§fn get_execution_namespace<'life0, 'life1, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_execution_namespace<'life0, 'life1, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
namespace scalar. Returns Ok(None) when
the row is absent or the field is unset. Dedicated point-read
used by the scanner per-candidate filter (should_skip_candidate)
to preserve the 1-HGET cost contract documented in
ff_engine::scanner::should_skip_candidate — describe_execution
is heavier (HGETALL / full snapshot) and unnecessary when only
the namespace scalar is needed. Read moreSource§fn list_edges<'life0, 'life1, 'async_trait>(
&'life0 self,
flow_id: &'life1 FlowId,
direction: EdgeDirection,
) -> Pin<Box<dyn Future<Output = Result<Vec<EdgeSnapshot>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn list_edges<'life0, 'life1, 'async_trait>(
&'life0 self,
flow_id: &'life1 FlowId,
direction: EdgeDirection,
) -> Pin<Box<dyn Future<Output = Result<Vec<EdgeSnapshot>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
edge:<edge_id> hash. Read moreSource§fn describe_edge<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
flow_id: &'life1 FlowId,
edge_id: &'life2 EdgeId,
) -> Pin<Box<dyn Future<Output = Result<Option<EdgeSnapshot>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn describe_edge<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
flow_id: &'life1 FlowId,
edge_id: &'life2 EdgeId,
) -> Pin<Box<dyn Future<Output = Result<Option<EdgeSnapshot>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Source§fn resolve_execution_flow_id<'life0, 'life1, 'async_trait>(
&'life0 self,
eid: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<Option<FlowId>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn resolve_execution_flow_id<'life0, 'life1, 'async_trait>(
&'life0 self,
eid: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<Option<FlowId>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn list_flows<'life0, 'async_trait>(
&'life0 self,
partition: PartitionKey,
cursor: Option<FlowId>,
limit: usize,
) -> Pin<Box<dyn Future<Output = Result<ListFlowsPage, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_flows<'life0, 'async_trait>(
&'life0 self,
partition: PartitionKey,
cursor: Option<FlowId>,
limit: usize,
) -> Pin<Box<dyn Future<Output = Result<ListFlowsPage, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn list_lanes<'life0, 'async_trait>(
&'life0 self,
cursor: Option<LaneId>,
limit: usize,
) -> Pin<Box<dyn Future<Output = Result<ListLanesPage, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_lanes<'life0, 'async_trait>(
&'life0 self,
cursor: Option<LaneId>,
limit: usize,
) -> Pin<Box<dyn Future<Output = Result<ListLanesPage, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn list_suspended<'life0, 'async_trait>(
&'life0 self,
partition: PartitionKey,
cursor: Option<ExecutionId>,
limit: usize,
) -> Pin<Box<dyn Future<Output = Result<ListSuspendedPage, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_suspended<'life0, 'async_trait>(
&'life0 self,
partition: PartitionKey,
cursor: Option<ExecutionId>,
limit: usize,
) -> Pin<Box<dyn Future<Output = Result<ListSuspendedPage, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
reason_code populated (issue
#183). Read moreSource§fn list_executions<'life0, 'async_trait>(
&'life0 self,
partition: PartitionKey,
cursor: Option<ExecutionId>,
limit: usize,
) -> Pin<Box<dyn Future<Output = Result<ListExecutionsPage, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_executions<'life0, 'async_trait>(
&'life0 self,
partition: PartitionKey,
cursor: Option<ExecutionId>,
limit: usize,
) -> Pin<Box<dyn Future<Output = Result<ListExecutionsPage, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn deliver_signal<'life0, 'async_trait>(
&'life0 self,
args: DeliverSignalArgs,
) -> Pin<Box<dyn Future<Output = Result<DeliverSignalResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn deliver_signal<'life0, 'async_trait>(
&'life0 self,
args: DeliverSignalArgs,
) -> Pin<Box<dyn Future<Output = Result<DeliverSignalResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn deliver_approval_signal<'life0, 'async_trait>(
&'life0 self,
args: DeliverApprovalSignalArgs,
) -> Pin<Box<dyn Future<Output = Result<DeliverSignalResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn deliver_approval_signal<'life0, 'async_trait>(
&'life0 self,
args: DeliverApprovalSignalArgs,
) -> Pin<Box<dyn Future<Output = Result<DeliverSignalResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn claim_resumed_execution<'life0, 'async_trait>(
&'life0 self,
args: ClaimResumedExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<ClaimResumedExecutionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn claim_resumed_execution<'life0, 'async_trait>(
&'life0 self,
args: ClaimResumedExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<ClaimResumedExecutionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Self::deliver_signal) and now needs a worker to pick up the
same attempt index. Read moreSource§fn read_execution_state<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<Option<PublicState>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn read_execution_state<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<Option<PublicState>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
public_state read used by the
GET /v1/executions/{id}/state HTTP route. Returns Ok(None)
when the execution is missing. Default Unavailable.Source§fn read_execution_info<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<Option<ExecutionInfo>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn read_execution_info<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<Option<ExecutionInfo>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
GET /v1/executions/{id} HTTP route. Returns the legacy
ExecutionInfo wire shape (not the decoupled
ExecutionSnapshot) so the existing HTTP response bytes stay
identical across the migration. Read moreSource§fn get_execution_result<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<Option<Vec<u8>>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_execution_result<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<Option<Vec<u8>>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Ok(None) when the execution is missing, not
yet complete, or its payload was trimmed by retention policy.Source§fn list_pending_waitpoints<'life0, 'async_trait>(
&'life0 self,
args: ListPendingWaitpointsArgs,
) -> Pin<Box<dyn Future<Output = Result<ListPendingWaitpointsResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_pending_waitpoints<'life0, 'async_trait>(
&'life0 self,
args: ListPendingWaitpointsArgs,
) -> Pin<Box<dyn Future<Output = Result<ListPendingWaitpointsResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
PendingWaitpointInfo shape; Stage D ships the §8 HMAC
sanitisation + (token_kid, token_fingerprint) schema.Source§fn cancel_execution<'life0, 'async_trait>(
&'life0 self,
args: CancelExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<CancelExecutionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn cancel_execution<'life0, 'async_trait>(
&'life0 self,
args: CancelExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<CancelExecutionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn revoke_lease<'life0, 'async_trait>(
&'life0 self,
args: RevokeLeaseArgs,
) -> Pin<Box<dyn Future<Output = Result<RevokeLeaseResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn revoke_lease<'life0, 'async_trait>(
&'life0 self,
args: RevokeLeaseArgs,
) -> Pin<Box<dyn Future<Output = Result<RevokeLeaseResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn change_priority<'life0, 'async_trait>(
&'life0 self,
args: ChangePriorityArgs,
) -> Pin<Box<dyn Future<Output = Result<ChangePriorityResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn change_priority<'life0, 'async_trait>(
&'life0 self,
args: ChangePriorityArgs,
) -> Pin<Box<dyn Future<Output = Result<ChangePriorityResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn replay_execution<'life0, 'async_trait>(
&'life0 self,
args: ReplayExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<ReplayExecutionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn replay_execution<'life0, 'async_trait>(
&'life0 self,
args: ReplayExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<ReplayExecutionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn cancel_flow_header<'life0, 'async_trait>(
&'life0 self,
args: CancelFlowArgs,
) -> Pin<Box<dyn Future<Output = Result<CancelFlowHeader, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn cancel_flow_header<'life0, 'async_trait>(
&'life0 self,
args: CancelFlowArgs,
) -> Pin<Box<dyn Future<Output = Result<CancelFlowHeader, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
cancel_flow — run the
atomic flow-state flip (Valkey: ff_cancel_flow FCALL; Postgres:
cancel_flow_once tx), decode policy + membership, and surface
the flow_already_terminal idempotency branch as a first-class
[CancelFlowHeader::AlreadyTerminal] so the Server can build
the wire CancelFlowResult without reaching for a raw
Client. Separate from the existing
EngineBackend::cancel_flow entry point (which takes the
enum-typed (policy, wait) split and returns the wait-collapsed
CancelFlowResult) because the Server owns its own
wait-dispatch + member-cancel machinery via
EngineBackend::cancel_execution + backlog ack. Read moreSource§fn ack_cancel_member<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
flow_id: &'life1 FlowId,
execution_id: &'life2 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn ack_cancel_member<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
flow_id: &'life1 FlowId,
execution_id: &'life2 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
cancel_all flow has completed its per-member cancel. Drains
the member from the flow’s pending_cancels set and, if empty,
removes the flow from the partition-level cancel_backlog
(Valkey: ff_ack_cancel_member FCALL; Postgres: table write —
default Unavailable until Wave 9). Read moreSource§fn create_flow<'life0, 'async_trait>(
&'life0 self,
args: CreateFlowArgs,
) -> Pin<Box<dyn Future<Output = Result<CreateFlowResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn create_flow<'life0, 'async_trait>(
&'life0 self,
args: CreateFlowArgs,
) -> Pin<Box<dyn Future<Output = Result<CreateFlowResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn add_execution_to_flow<'life0, 'async_trait>(
&'life0 self,
args: AddExecutionToFlowArgs,
) -> Pin<Box<dyn Future<Output = Result<AddExecutionToFlowResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn add_execution_to_flow<'life0, 'async_trait>(
&'life0 self,
args: AddExecutionToFlowArgs,
) -> Pin<Box<dyn Future<Output = Result<AddExecutionToFlowResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn stage_dependency_edge<'life0, 'async_trait>(
&'life0 self,
args: StageDependencyEdgeArgs,
) -> Pin<Box<dyn Future<Output = Result<StageDependencyEdgeResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn stage_dependency_edge<'life0, 'async_trait>(
&'life0 self,
args: StageDependencyEdgeArgs,
) -> Pin<Box<dyn Future<Output = Result<StageDependencyEdgeResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
graph_revision — stale rev returns Contention(StaleGraphRevision).Source§fn apply_dependency_to_child<'life0, 'async_trait>(
&'life0 self,
args: ApplyDependencyToChildArgs,
) -> Pin<Box<dyn Future<Output = Result<ApplyDependencyToChildResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn apply_dependency_to_child<'life0, 'async_trait>(
&'life0 self,
args: ApplyDependencyToChildArgs,
) -> Pin<Box<dyn Future<Output = Result<ApplyDependencyToChildResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn cascade_completion<'life0, 'life1, 'async_trait>(
&'life0 self,
payload: &'life1 CompletionPayload,
) -> Pin<Box<dyn Future<Output = Result<CascadeOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn cascade_completion<'life0, 'life1, 'async_trait>(
&'life0 self,
payload: &'life1 CompletionPayload,
) -> Pin<Box<dyn Future<Output = Result<CascadeOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
ff-engine::completion_listener::spawn_dispatch_loop (PR-7b
Cluster 4) to trait-route the post-completion DAG-promotion
path through Arc<dyn EngineBackend>. Read moreSource§fn backend_label(&self) -> &'static str
fn backend_label(&self) -> &'static str
"unknown" so legacy impl EngineBackend blocks that
have not upgraded keep compiling; every in-tree backend
overrides — ValkeyBackend → "valkey", PostgresBackend →
"postgres".Source§fn ping<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn ping<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
PING;
Postgres: SELECT 1.Source§fn cancel_flow<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 FlowId,
policy: CancelFlowPolicy,
wait: CancelFlowWait,
) -> Pin<Box<dyn Future<Output = Result<CancelFlowResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn cancel_flow<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 FlowId,
policy: CancelFlowPolicy,
wait: CancelFlowWait,
) -> Pin<Box<dyn Future<Output = Result<CancelFlowResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn set_edge_group_policy<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
flow_id: &'life1 FlowId,
downstream_execution_id: &'life2 ExecutionId,
policy: EdgeDependencyPolicy,
) -> Pin<Box<dyn Future<Output = Result<SetEdgeGroupPolicyResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn set_edge_group_policy<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
flow_id: &'life1 FlowId,
downstream_execution_id: &'life2 ExecutionId,
policy: EdgeDependencyPolicy,
) -> Pin<Box<dyn Future<Output = Result<SetEdgeGroupPolicyResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
add_dependency(... -> downstream_execution_id) — the backend
rejects with EngineError::Conflict if edges have already
been staged for this group. Read moreSource§fn report_usage<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_handle: &'life1 Handle,
budget: &'life2 BudgetId,
dimensions: UsageDimensions,
) -> Pin<Box<dyn Future<Output = Result<ReportUsageResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn report_usage<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_handle: &'life1 Handle,
budget: &'life2 BudgetId,
dimensions: UsageDimensions,
) -> Pin<Box<dyn Future<Output = Result<ReportUsageResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
ReportUsageResult variant; backends enforce
idempotency via the caller-supplied
[UsageDimensions::dedup_key] (RFC-012 §R7.2.3 — replaces
the pre-Round-7 AdmissionDecision return).Source§fn create_budget<'life0, 'async_trait>(
&'life0 self,
args: CreateBudgetArgs,
) -> Pin<Box<dyn Future<Output = Result<CreateBudgetResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn create_budget<'life0, 'async_trait>(
&'life0 self,
args: CreateBudgetArgs,
) -> Pin<Box<dyn Future<Output = Result<CreateBudgetResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn reset_budget<'life0, 'async_trait>(
&'life0 self,
args: ResetBudgetArgs,
) -> Pin<Box<dyn Future<Output = Result<ResetBudgetResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn reset_budget<'life0, 'async_trait>(
&'life0 self,
args: ResetBudgetArgs,
) -> Pin<Box<dyn Future<Output = Result<ResetBudgetResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn create_quota_policy<'life0, 'async_trait>(
&'life0 self,
args: CreateQuotaPolicyArgs,
) -> Pin<Box<dyn Future<Output = Result<CreateQuotaPolicyResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn create_quota_policy<'life0, 'async_trait>(
&'life0 self,
args: CreateQuotaPolicyArgs,
) -> Pin<Box<dyn Future<Output = Result<CreateQuotaPolicyResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn get_budget_status<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 BudgetId,
) -> Pin<Box<dyn Future<Output = Result<BudgetStatus, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_budget_status<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 BudgetId,
) -> Pin<Box<dyn Future<Output = Result<BudgetStatus, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn report_usage_admin<'life0, 'life1, 'async_trait>(
&'life0 self,
budget_id: &'life1 BudgetId,
args: ReportUsageAdminArgs,
) -> Pin<Box<dyn Future<Output = Result<ReportUsageResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn report_usage_admin<'life0, 'life1, 'async_trait>(
&'life0 self,
budget_id: &'life1 BudgetId,
args: ReportUsageAdminArgs,
) -> Pin<Box<dyn Future<Output = Result<ReportUsageResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
report_usage (row 9 + RFC-017 §5 round-1 F4).
Distinct from the existing Self::report_usage which takes
a worker handle — the admin path has no lease context.Source§fn record_spend<'life0, 'async_trait>(
&'life0 self,
args: RecordSpendArgs,
) -> Pin<Box<dyn Future<Output = Result<ReportUsageResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn record_spend<'life0, 'async_trait>(
&'life0 self,
args: RecordSpendArgs,
) -> Pin<Box<dyn Future<Output = Result<ReportUsageResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn release_budget<'life0, 'async_trait>(
&'life0 self,
args: ReleaseBudgetArgs,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn release_budget<'life0, 'async_trait>(
&'life0 self,
args: ReleaseBudgetArgs,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn release_admission<'life0, 'async_trait>(
&'life0 self,
args: ReleaseAdmissionArgs,
) -> Pin<Box<dyn Future<Output = Result<ReleaseAdmissionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn release_admission<'life0, 'async_trait>(
&'life0 self,
args: ReleaseAdmissionArgs,
) -> Pin<Box<dyn Future<Output = Result<ReleaseAdmissionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Self::check_admission / ff_check_admission_and_record but
for which issue_claim_grant subsequently failed. Idempotent:
releasing an already-released slot is a no-op. Read moreSource§fn read_quota_policy_limits<'life0, 'life1, 'async_trait>(
&'life0 self,
quota_policy_id: &'life1 QuotaPolicyId,
) -> Pin<Box<dyn Future<Output = Result<Option<QuotaPolicyLimits>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn read_quota_policy_limits<'life0, 'life1, 'async_trait>(
&'life0 self,
quota_policy_id: &'life1 QuotaPolicyId,
) -> Pin<Box<dyn Future<Output = Result<Option<QuotaPolicyLimits>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
ff:quota:{K}:def that
ff_scheduler used pre-FF #511. Returns None when the
policy row is absent; absence is a well-defined “no admission
configured” signal, not an error.Source§fn rotate_waitpoint_hmac_secret_all<'life0, 'async_trait>(
&'life0 self,
args: RotateWaitpointHmacSecretAllArgs,
) -> Pin<Box<dyn Future<Output = Result<RotateWaitpointHmacSecretAllResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn rotate_waitpoint_hmac_secret_all<'life0, 'async_trait>(
&'life0 self,
args: RotateWaitpointHmacSecretAllArgs,
) -> Pin<Box<dyn Future<Output = Result<RotateWaitpointHmacSecretAllResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn seed_waitpoint_hmac_secret<'life0, 'async_trait>(
&'life0 self,
args: SeedWaitpointHmacSecretArgs,
) -> Pin<Box<dyn Future<Output = Result<SeedOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn seed_waitpoint_hmac_secret<'life0, 'async_trait>(
&'life0 self,
args: SeedWaitpointHmacSecretArgs,
) -> Pin<Box<dyn Future<Output = Result<SeedOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn read_stream<'life0, 'life1, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
attempt_index: AttemptIndex,
from: StreamCursor,
to: StreamCursor,
count_limit: u64,
) -> Pin<Box<dyn Future<Output = Result<StreamFrames, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn read_stream<'life0, 'life1, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
attempt_index: AttemptIndex,
from: StreamCursor,
to: StreamCursor,
count_limit: u64,
) -> Pin<Box<dyn Future<Output = Result<StreamFrames, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn tail_stream<'life0, 'life1, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
attempt_index: AttemptIndex,
after: StreamCursor,
block_ms: u64,
count_limit: u64,
visibility: TailVisibility,
) -> Pin<Box<dyn Future<Output = Result<StreamFrames, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn tail_stream<'life0, 'life1, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
attempt_index: AttemptIndex,
after: StreamCursor,
block_ms: u64,
count_limit: u64,
visibility: TailVisibility,
) -> Pin<Box<dyn Future<Output = Result<StreamFrames, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn read_summary<'life0, 'life1, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
attempt_index: AttemptIndex,
) -> Pin<Box<dyn Future<Output = Result<Option<SummaryDocument>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn read_summary<'life0, 'life1, 'async_trait>(
&'life0 self,
execution_id: &'life1 ExecutionId,
attempt_index: AttemptIndex,
) -> Pin<Box<dyn Future<Output = Result<Option<SummaryDocument>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn subscribe_completion<'life0, 'life1, 'async_trait>(
&'life0 self,
_cursor: StreamCursor,
filter: &'life1 ScannerFilter,
) -> Pin<Box<dyn Future<Output = Result<CompletionSubscription, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn subscribe_completion<'life0, 'life1, 'async_trait>(
&'life0 self,
_cursor: StreamCursor,
filter: &'life1 ScannerFilter,
) -> Pin<Box<dyn Future<Output = Result<CompletionSubscription, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn subscribe_lease_history<'life0, 'life1, 'async_trait>(
&'life0 self,
cursor: StreamCursor,
filter: &'life1 ScannerFilter,
) -> Pin<Box<dyn Future<Output = Result<LeaseHistorySubscription, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn subscribe_lease_history<'life0, 'life1, 'async_trait>(
&'life0 self,
cursor: StreamCursor,
filter: &'life1 ScannerFilter,
) -> Pin<Box<dyn Future<Output = Result<LeaseHistorySubscription, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn subscribe_signal_delivery<'life0, 'life1, 'async_trait>(
&'life0 self,
cursor: StreamCursor,
filter: &'life1 ScannerFilter,
) -> Pin<Box<dyn Future<Output = Result<SignalDeliverySubscription, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn subscribe_signal_delivery<'life0, 'life1, 'async_trait>(
&'life0 self,
cursor: StreamCursor,
filter: &'life1 ScannerFilter,
) -> Pin<Box<dyn Future<Output = Result<SignalDeliverySubscription, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn mark_lease_expired_if_due<'life0, 'life1, 'async_trait>(
&'life0 self,
partition: Partition,
execution_id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn mark_lease_expired_if_due<'life0, 'life1, 'async_trait>(
&'life0 self,
partition: Partition,
execution_id: &'life1 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn promote_delayed<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
partition: Partition,
_lane: &'life1 LaneId,
execution_id: &'life2 ExecutionId,
now_ms: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn promote_delayed<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
partition: Partition,
_lane: &'life1 LaneId,
execution_id: &'life2 ExecutionId,
now_ms: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
eligible_now once its delay_until has passed. Read moreSource§fn close_waitpoint<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
partition: Partition,
_execution_id: &'life1 ExecutionId,
waitpoint_id: &'life2 str,
now_ms: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn close_waitpoint<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
partition: Partition,
_execution_id: &'life1 ExecutionId,
waitpoint_id: &'life2 str,
now_ms: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Source§fn expire_execution<'life0, 'life1, 'async_trait>(
&'life0 self,
partition: Partition,
execution_id: &'life1 ExecutionId,
phase: ExpirePhase,
now_ms: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn expire_execution<'life0, 'life1, 'async_trait>(
&'life0 self,
partition: Partition,
execution_id: &'life1 ExecutionId,
phase: ExpirePhase,
now_ms: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
phase discriminates which of the two
scanner paths is calling so the backend can preserve diagnostic
breadcrumbs without forking the surface. Read moreSource§fn expire_suspension<'life0, 'life1, 'async_trait>(
&'life0 self,
partition: Partition,
execution_id: &'life1 ExecutionId,
_now_ms: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn expire_suspension<'life0, 'life1, 'async_trait>(
&'life0 self,
partition: Partition,
execution_id: &'life1 ExecutionId,
_now_ms: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn project_flow_summary<'life0, 'life1, 'async_trait>(
&'life0 self,
partition: Partition,
flow_id: &'life1 FlowId,
now_ms: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<bool, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn project_flow_summary<'life0, 'life1, 'async_trait>(
&'life0 self,
partition: Partition,
flow_id: &'life1 FlowId,
now_ms: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<bool, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
public_flow_state + per-state counts, and write them
to the flow summary projection. Returns Ok(true) when the
summary was updated, Ok(false) when the flow had no members
or the index entry was defensively pruned (core missing). Read moreSource§fn trim_retention<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
partition: Partition,
lane_id: &'life1 LaneId,
retention_ms: u64,
now_ms: TimestampMs,
batch_size: u32,
filter: &'life2 ScannerFilter,
) -> Pin<Box<dyn Future<Output = Result<u32, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn trim_retention<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
partition: Partition,
lane_id: &'life1 LaneId,
retention_ms: u64,
now_ms: TimestampMs,
batch_size: u32,
filter: &'life2 ScannerFilter,
) -> Pin<Box<dyn Future<Output = Result<u32, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
batch_size). Read moreSource§fn renew_lease<'life0, 'async_trait>(
&'life0 self,
args: RenewLeaseArgs,
) -> Pin<Box<dyn Future<Output = Result<RenewLeaseResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn renew_lease<'life0, 'async_trait>(
&'life0 self,
args: RenewLeaseArgs,
) -> Pin<Box<dyn Future<Output = Result<RenewLeaseResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
renew_lease — peer of Self::renew that
takes a fence triple instead of a worker Handle.Source§fn complete_execution<'life0, 'async_trait>(
&'life0 self,
args: CompleteExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<CompleteExecutionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn complete_execution<'life0, 'async_trait>(
&'life0 self,
args: CompleteExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<CompleteExecutionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
complete_execution — peer of Self::complete
that takes a fence triple instead of a worker Handle. See
the group preamble above for cairn-migration context.Source§fn fail_execution<'life0, 'async_trait>(
&'life0 self,
args: FailExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<FailExecutionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn fail_execution<'life0, 'async_trait>(
&'life0 self,
args: FailExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<FailExecutionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fail_execution — peer of Self::fail that
takes a fence triple instead of a worker Handle.Source§fn resume_execution<'life0, 'async_trait>(
&'life0 self,
args: ResumeExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<ResumeExecutionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn resume_execution<'life0, 'async_trait>(
&'life0 self,
args: ResumeExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<ResumeExecutionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
resume_execution — transitions a suspended
execution back to runnable. Distinct from
Self::claim_from_resume_grant (which mints a worker handle
against an already-eligible resumed execution): this method is
the lifecycle transition primitive the control plane calls
when an operator / auto-resume policy moves a suspended
execution forward. Read moreSource§fn check_admission<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
quota_policy_id: &'life1 QuotaPolicyId,
_dimension: &'life2 str,
args: CheckAdmissionArgs,
) -> Pin<Box<dyn Future<Output = Result<CheckAdmissionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn check_admission<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
quota_policy_id: &'life1 QuotaPolicyId,
_dimension: &'life2 str,
args: CheckAdmissionArgs,
) -> Pin<Box<dyn Future<Output = Result<CheckAdmissionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
check_admission_and_record — atomic admission
check against a quota policy. Callers supply the policy id +
dimension (quota keys live on their own {q:<policy>}
partition that cannot be derived from execution_id, so these
travel outside CheckAdmissionArgs). dimension defaults
to "default" inside the Valkey body when the caller passes
an empty string — matches cairn’s pre-migration default.Source§fn evaluate_flow_eligibility<'life0, 'async_trait>(
&'life0 self,
args: EvaluateFlowEligibilityArgs,
) -> Pin<Box<dyn Future<Output = Result<EvaluateFlowEligibilityResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn evaluate_flow_eligibility<'life0, 'async_trait>(
&'life0 self,
args: EvaluateFlowEligibilityArgs,
) -> Pin<Box<dyn Future<Output = Result<EvaluateFlowEligibilityResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
evaluate_flow_eligibility — read-only check
that returns the execution’s current eligibility state
(eligible, blocked_by_dependencies, or a backend-specific
status string). Called by cairn’s dependency-resolution path
to decide whether a downstream execution can proceed.Source§fn claim_execution<'life0, 'async_trait>(
&'life0 self,
args: ClaimExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<ClaimExecutionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn claim_execution<'life0, 'async_trait>(
&'life0 self,
args: ClaimExecutionArgs,
) -> Pin<Box<dyn Future<Output = Result<ClaimExecutionResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn issue_grant_and_claim<'life0, 'async_trait>(
&'life0 self,
args: IssueGrantAndClaimArgs,
) -> Pin<Box<dyn Future<Output = Result<ClaimGrantOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn issue_grant_and_claim<'life0, 'async_trait>(
&'life0 self,
args: IssueGrantAndClaimArgs,
) -> Pin<Box<dyn Future<Output = Result<ClaimGrantOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn read_exec_core_fields<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
partition: Partition,
execution_id: &'life1 ExecutionId,
fields: &'life2 [&'life3 str],
) -> Pin<Box<dyn Future<Output = Result<HashMap<String, Option<String>>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn read_exec_core_fields<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
partition: Partition,
execution_id: &'life1 ExecutionId,
fields: &'life2 [&'life3 str],
) -> Pin<Box<dyn Future<Output = Result<HashMap<String, Option<String>>, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
exec_core hash for a given
execution. Returns a map of field-name → OptionHGET/HMGET on ExecKeyContext::core()
route through this trait method (cairn #436 / PR-7b Wave 0a). Read moreSource§fn server_time_ms<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn server_time_ms<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn register_worker<'life0, 'async_trait>(
&'life0 self,
args: RegisterWorkerArgs,
) -> Pin<Box<dyn Future<Output = Result<RegisterWorkerOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn register_worker<'life0, 'async_trait>(
&'life0 self,
args: RegisterWorkerArgs,
) -> Pin<Box<dyn Future<Output = Result<RegisterWorkerOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn heartbeat_worker<'life0, 'async_trait>(
&'life0 self,
args: HeartbeatWorkerArgs,
) -> Pin<Box<dyn Future<Output = Result<HeartbeatWorkerOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn heartbeat_worker<'life0, 'async_trait>(
&'life0 self,
args: HeartbeatWorkerArgs,
) -> Pin<Box<dyn Future<Output = Result<HeartbeatWorkerOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn mark_worker_dead<'life0, 'async_trait>(
&'life0 self,
args: MarkWorkerDeadArgs,
) -> Pin<Box<dyn Future<Output = Result<MarkWorkerDeadOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn mark_worker_dead<'life0, 'async_trait>(
&'life0 self,
args: MarkWorkerDeadArgs,
) -> Pin<Box<dyn Future<Output = Result<MarkWorkerDeadOutcome, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn list_expired_leases<'life0, 'async_trait>(
&'life0 self,
args: ListExpiredLeasesArgs,
) -> Pin<Box<dyn Future<Output = Result<ListExpiredLeasesResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_expired_leases<'life0, 'async_trait>(
&'life0 self,
args: ListExpiredLeasesArgs,
) -> Pin<Box<dyn Future<Output = Result<ListExpiredLeasesResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn list_workers<'life0, 'async_trait>(
&'life0 self,
args: ListWorkersArgs,
) -> Pin<Box<dyn Future<Output = Result<ListWorkersResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_workers<'life0, 'async_trait>(
&'life0 self,
args: ListWorkersArgs,
) -> Pin<Box<dyn Future<Output = Result<ListWorkersResult, EngineError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn scan_eligible_executions<'life0, 'async_trait>(
&'life0 self,
_args: ScanEligibleArgs,
) -> Pin<Box<dyn Future<Output = Result<Vec<ExecutionId>, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn scan_eligible_executions<'life0, 'async_trait>(
&'life0 self,
_args: ScanEligibleArgs,
) -> Pin<Box<dyn Future<Output = Result<Vec<ExecutionId>, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Source§fn issue_claim_grant<'life0, 'async_trait>(
&'life0 self,
_args: IssueClaimGrantArgs,
) -> Pin<Box<dyn Future<Output = Result<IssueClaimGrantOutcome, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn issue_claim_grant<'life0, 'async_trait>(
&'life0 self,
_args: IssueClaimGrantArgs,
) -> Pin<Box<dyn Future<Output = Result<IssueClaimGrantOutcome, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Source§fn block_route<'life0, 'async_trait>(
&'life0 self,
_args: BlockRouteArgs,
) -> Pin<Box<dyn Future<Output = Result<BlockRouteOutcome, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn block_route<'life0, 'async_trait>(
&'life0 self,
_args: BlockRouteArgs,
) -> Pin<Box<dyn Future<Output = Result<BlockRouteOutcome, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Source§fn resolve_dependency<'life0, 'async_trait>(
&'life0 self,
_args: ResolveDependencyArgs,
) -> Pin<Box<dyn Future<Output = Result<ResolveDependencyOutcome, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn resolve_dependency<'life0, 'async_trait>(
&'life0 self,
_args: ResolveDependencyArgs,
) -> Pin<Box<dyn Future<Output = Result<ResolveDependencyOutcome, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
AlreadyResolved on replay). Read moreSource§fn block_execution_for_admission<'life0, 'async_trait>(
&'life0 self,
_args: BlockExecutionForAdmissionArgs,
) -> Pin<Box<dyn Future<Output = Result<BlockExecutionForAdmissionOutcome, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn block_execution_for_admission<'life0, 'async_trait>(
&'life0 self,
_args: BlockExecutionForAdmissionArgs,
) -> Pin<Box<dyn Future<Output = Result<BlockExecutionForAdmissionOutcome, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
BlockingReason selects both the
eligibility state written to exec_core and the target
blocked_<reason> lane index. Valkey wraps the existing
ff_block_execution_for_admission FCALL (KEYS=3); PG/SQLite
write the equivalent row transition. Read moreSource§fn read_budget_usage_and_limits<'life0, 'life1, 'async_trait>(
&'life0 self,
_budget_id: &'life1 BudgetId,
) -> Pin<Box<dyn Future<Output = Result<BudgetUsageAndLimits, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn read_budget_usage_and_limits<'life0, 'life1, 'async_trait>(
&'life0 self,
_budget_id: &'life1 BudgetId,
) -> Pin<Box<dyn Future<Output = Result<BudgetUsageAndLimits, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
ff:budget:{K}:{id}:limits + ff:budget:{K}:{id}:usage.
Returns BudgetUsageAndLimits::empty when the limits hash
is absent (“no limits configured” — not an error).Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
Source§fn unblock_execution<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
_partition: Partition,
_lane_id: &'life1 LaneId,
_execution_id: &'life2 ExecutionId,
_expected_blocking_reason: &'life3 str,
_now_ms: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self: 'async_trait,
fn unblock_execution<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
_partition: Partition,
_lane_id: &'life1 LaneId,
_execution_id: &'life2 ExecutionId,
_expected_blocking_reason: &'life3 str,
_now_ms: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self: 'async_trait,
eligible_now once its blocking condition has cleared (budget
under limit, quota window drained, or a capable worker has come
online). expected_blocking_reason discriminates which of the
blocked:{budget,quota,route} sets the execution is leaving and
also fences against a stale unblock (Lua rejects if the core’s
blocking_reason no longer matches). Read moreSource§fn drain_sibling_cancel_group<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_flow_partition: Partition,
_flow_id: &'life1 FlowId,
_downstream_eid: &'life2 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn drain_sibling_cancel_group<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_flow_partition: Partition,
_flow_id: &'life1 FlowId,
_downstream_eid: &'life2 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<(), EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Source§fn reconcile_sibling_cancel_group<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_flow_partition: Partition,
_flow_id: &'life1 FlowId,
_downstream_eid: &'life2 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<SiblingCancelReconcileAction, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn reconcile_sibling_cancel_group<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_flow_partition: Partition,
_flow_id: &'life1 FlowId,
_downstream_eid: &'life2 ExecutionId,
) -> Pin<Box<dyn Future<Output = Result<SiblingCancelReconcileAction, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Source§fn reconcile_execution_index<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_partition: Partition,
_lanes: &'life1 [LaneId],
_filter: &'life2 ScannerFilter,
) -> Pin<Box<dyn Future<Output = Result<ReconcileCounts, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn reconcile_execution_index<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_partition: Partition,
_lanes: &'life1 [LaneId],
_filter: &'life2 ScannerFilter,
) -> Pin<Box<dyn Future<Output = Result<ReconcileCounts, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
ff:idx:{p:N}:all_executions
and verifies each execution appears in the correct scheduling
sorted set (eligible / delayed / blocked:* / active /
suspended / terminal) for its current (lifecycle_phase, eligibility_state, ownership_state) triple. Phase 1 is
log-only; auto-fix is deferred to a later phase (RFC-010 §6.14).Source§fn reconcile_budget_counters<'life0, 'async_trait>(
&'life0 self,
_partition: Partition,
_now_ms: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<ReconcileCounts, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn reconcile_budget_counters<'life0, 'async_trait>(
&'life0 self,
_partition: Partition,
_now_ms: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<ReconcileCounts, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
ff:budget:{b:M}:policies_idx,
reads each budget’s definition / usage / limits, and reconciles
the breached_at marker against hard limits. Resetting budgets
(non-zero reset_interval_ms) are skipped — they are handled
by the budget_reset scanner (cluster 2). Drops index entries
for budgets whose definition hash has been deleted (retention
purge / manual). RFC-008 §Budget Reconciliation, RFC-010 §6.5.Source§fn reconcile_quota_counters<'life0, 'async_trait>(
&'life0 self,
_partition: Partition,
_now_ms: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<ReconcileCounts, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn reconcile_quota_counters<'life0, 'async_trait>(
&'life0 self,
_partition: Partition,
_now_ms: TimestampMs,
) -> Pin<Box<dyn Future<Output = Result<ReconcileCounts, EngineError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
ff:quota:{q:M}:policies_idx,
trims expired entries from rate-limit sliding windows, and
recomputes each policy’s concurrency counter by walking its
admitted_set and pruning entries whose admission guard key
has TTLed out. RFC-008 §Quota Reconciliation, RFC-010 §6.6.Auto Trait Implementations§
impl Freeze for PostgresBackend
impl !RefUnwindSafe for PostgresBackend
impl Send for PostgresBackend
impl Sync for PostgresBackend
impl Unpin for PostgresBackend
impl UnsafeUnpin for PostgresBackend
impl !UnwindSafe for PostgresBackend
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more