pub struct EffectRecord {Show 23 fields
pub id: EffectId,
pub key: EffectKey,
pub kind: EffectKind,
pub status: EffectStatus,
pub input: Option<Value>,
pub input_fingerprint: Option<String>,
pub output: Option<Value>,
pub last_error: Option<ErrorRecord>,
pub created_by: Option<String>,
pub attempt_count: u32,
pub may_have_applied: bool,
pub compensation_attempts: u32,
pub approved: bool,
pub next_attempt_at: Option<SystemTime>,
pub attempt_started_at: Option<SystemTime>,
pub attempt_ended_at: Option<SystemTime>,
pub lease_owner: Option<WorkerId>,
pub lease_epoch: u64,
pub lease_expires_at: Option<SystemTime>,
pub version: u64,
pub created_at: SystemTime,
pub updated_at: SystemTime,
pub committed_at: Option<SystemTime>,
}Expand description
The durable state of one effect.
The methods are pure: they check a change against the record and apply it in memory. Stores call them inside a transaction and persist the result, so the rules are the same for every backend.
Fields§
§id: EffectIdRecord id.
key: EffectKeyLogical identity, unique per store.
kind: EffectKindThe effect’s kind.
status: EffectStatusCurrent status.
input: Option<Value>The input, redacted for storage.
input_fingerprint: Option<String>Hash of the unredacted input.
output: Option<Value>The latest action or verification result.
last_error: Option<ErrorRecord>The latest recorded failure.
created_by: Option<String>Who asked for the effect.
attempt_count: u32Attempts started so far.
may_have_applied: boolAn attempt may have applied the effect, and no evidence has shown
otherwise since. Set when an outcome becomes unknown; cleared only by
a trusted verification or an operator. While it is set, the effect
cannot become Failed through a failed attempt (see Self::apply).
compensation_attempts: u32Compensation attempts started so far.
approved: boolThe effect was approved, so it is not asked again, even after a restart.
next_attempt_at: Option<SystemTime>When a scheduled retry may start.
attempt_started_at: Option<SystemTime>When the latest attempt started.
attempt_ended_at: Option<SystemTime>When the latest attempt was last known to be in flight: the first
transition out of Executing after it started. Settle delays count
from here.
lease_owner: Option<WorkerId>Current lease holder, if any. The lease may have expired.
lease_epoch: u64Fencing token; incremented by every lease acquisition.
lease_expires_at: Option<SystemTime>When the current lease lapses.
version: u64Incremented by every transition. Lease operations do not change it.
created_at: SystemTimeCreation time.
updated_at: SystemTimeTime of the latest change.
committed_at: Option<SystemTime>When the effect committed.
Implementations§
Source§impl EffectRecord
impl EffectRecord
Sourcepub fn live_lease_owner(&self, now: SystemTime) -> Option<&WorkerId>
pub fn live_lease_owner(&self, now: SystemTime) -> Option<&WorkerId>
The holder of a lease that is still live at now.
Sourcepub fn acquire_lease(
&mut self,
owner: &WorkerId,
now: SystemTime,
ttl: Duration,
) -> Result<Lease, StoreError>
pub fn acquire_lease( &mut self, owner: &WorkerId, now: SystemTime, ttl: Duration, ) -> Result<Lease, StoreError>
Takes the lease for ttl, provided nobody holds a live one.
§Errors
StoreError::LeaseHeld if a live lease exists, even one held by
owner: two tasks of one worker must not run the same effect either.
Sourcepub fn renew_lease(
&mut self,
lease: &Lease,
now: SystemTime,
ttl: Duration,
) -> Result<Lease, StoreError>
pub fn renew_lease( &mut self, lease: &Lease, now: SystemTime, ttl: Duration, ) -> Result<Lease, StoreError>
Extends lease to now + ttl.
§Errors
StoreError::LeaseLost if the lease expired or was taken over.
Renewal is strict: an expired lease cannot be revived, even if nobody
else took it.
Sourcepub fn release_lease(&mut self, lease: &Lease) -> bool
pub fn release_lease(&mut self, lease: &Lease) -> bool
Clears lease if it is still the current one, expired or not.
Returns whether anything changed.
Sourcepub fn apply(
&mut self,
request: TransitionRequest,
) -> Result<EffectEvent, StoreError>
pub fn apply( &mut self, request: TransitionRequest, ) -> Result<EffectEvent, StoreError>
Applies request and returns the audit event to persist with it.
On error the record is unchanged.
Checks, in order: the lease (or the absence of a live one), the version, and the transition table. Then it updates the bookkeeping:
Transition::StartAttemptincrements the attempt count, stampsattempt_started_at, and clearsattempt_ended_at,next_attempt_atandoutput(an output stored before belongs to an attempt that did not settle the effect, so it must never be replayed); any transition out ofExecutingstampsattempt_ended_at;Transition::StartCompensationsetscompensation_attemptsto 1 andTransition::StartCompensationRetryincrements it; both clearnext_attempt_at;- a retry transition, including
Transition::ScheduleCompensationRetry, setsnext_attempt_at(defaultnow); - reaching
Committedstampscommitted_at; - reaching
Unknownsetsmay_have_applied; evidence that the effect did not apply clears it (VerificationNotApplied,ResolvedNotApplied, or aScheduleRetryout ofVerifying, which the runtime issues only after a trusted “not applied”); outputanderror, when given, replace the stored ones.
Failed must mean the effect did not apply. A failed attempt proves
that only for itself, so FailedDefinitively is refused while
may_have_applied is set (except for Read effects, which apply
nothing).
§Errors
StoreError::LeaseLost, StoreError::LeaseHeld,
StoreError::VersionConflict or StoreError::InvalidTransition.