Struct RunMachine
pub struct RunMachine {
pub gate: Lsn,
/* private fields */
}Fields§
§gate: LsnLSN of the run’s most recent record. A step function may run only once the log is durable through it.
Implementations§
§impl RunMachine
impl RunMachine
pub fn new(journal: &[RecordBuf], gate: Lsn) -> Result<Self, DeterminismError>
pub fn new(journal: &[RecordBuf], gate: Lsn) -> Result<Self, DeterminismError>
Builds a machine from a run’s journal (its records in log order, the
first being Start). gate is the LSN of the last record.
pub fn rebuild(
&mut self,
journal: &[RecordBuf],
gate: Lsn,
) -> Result<(), DeterminismError>
pub fn rebuild( &mut self, journal: &[RecordBuf], gate: Lsn, ) -> Result<(), DeterminismError>
Self::new in place: the machine becomes journal‘s run’s,
keeping its collections’ memory and its cache of operation names
(a shard reuses the machines of runs that ended or parked). After an
error the machine holds part of journal and must be rebuilt again
before use.
pub fn rebuild_drain(
&mut self,
journal: &mut Vec<RecordBuf>,
gate: Lsn,
) -> Result<(), DeterminismError>
pub fn rebuild_drain( &mut self, journal: &mut Vec<RecordBuf>, gate: Lsn, ) -> Result<(), DeterminismError>
Self::rebuild from a journal it may empty: the start record’s
names and payloads move into the run instead of being cloned (on a
wake they were cloned, then dropped with the decoded records, an
atomic each way on lines no cache held). journal is left empty,
its memory kept.
pub fn release(&mut self)
pub fn release(&mut self)
Lets go of the run: its collections are emptied (keeping their
memory) and its payloads and names dropped, so a machine kept for
Self::rebuild holds nothing of it.
pub fn reusable(&self) -> bool
pub fn reusable(&self) -> bool
Whether the machine is small enough to keep for Self::rebuild
(clearing a collection costs its capacity, not its length).
pub fn fresh(start: &RecordBuf, lsn: Lsn) -> Result<Self, DeterminismError>
pub fn fresh(start: &RecordBuf, lsn: Lsn) -> Result<Self, DeterminismError>
A fresh run: its journal is just the Start record at lsn.
pub fn info(&self) -> &RunInfo
pub fn run(&self) -> RunId
pub fn recorded_done(&self) -> Option<&(Status, Payload)>
pub fn recorded_done(&self) -> Option<&(Status, Payload)>
The recorded result, if the journal already holds Done.
pub fn is_replaying(&self) -> bool
pub fn pending_len(&self) -> usize
pub fn pending_len(&self) -> usize
Operations started and not yet resolved.
pub fn has_queued_deliveries(&self) -> bool
pub fn has_queued_deliveries(&self) -> bool
True while some started operation will be resolved by live work. Completions, updates or cancellations wait to be delivered to code.
pub fn delivers_only(&self, seq: Seq) -> bool
pub fn delivers_only(&self, seq: Seq) -> bool
The next delivery is seq’s live result and nothing could come
before or with it: nothing left to replay, no cancellation, no
other completion or update queued, no other operation pending, and
the step’s result is what its completion queued.
pub fn return_name(&mut self, name: Name)
pub fn return_name(&mut self, name: Name)
A live step’s result taken at once: when
it is the only delivery the run could take next (nothing left to
replay, no cancellation, no other operation pending, nothing queued,
no stream of the step to end), the step’s pending entry goes as
next would remove it on delivering the completion,
and the record to append comes back. None changes nothing: queue
the completion with complete instead.
A name take_live_step handed out, back
to the cache the next operation of that name takes it from.
pub fn take_live_step(&mut self, seq: Seq) -> Option<LiveRecord>
pub fn has_live_pending(&self) -> bool
pub fn is_idle(&self) -> bool
pub fn is_idle(&self) -> bool
Nothing is pending, queued or left to replay: the code has started no operation it waits for (an object between calls).
pub fn is_suspended(&self) -> bool
pub fn is_suspended(&self) -> bool
Every pending operation waits on time, a signal, a child or an outside completion, nothing is queued for delivery and replay is done: the run can be parked.
pub fn next_seq(&self) -> Seq
pub fn journal_size(&self) -> u32
pub fn journal_size(&self) -> u32
Journal operations the code has started so far. Deterministic, so code may decide on it (for example, when to continue as new).
pub fn key(&self, seq: Seq) -> String
pub fn key(&self, seq: Seq) -> String
The idempotency key for operation seq: stable across retries and
recovery, distinct across runs that reuse a workflow ID (including a
run that replaced this one by reset).
pub fn pending_name(&self, seq: Seq) -> Option<&str>
pub fn pending_name(&self, seq: Seq) -> Option<&str>
The name of a started, unresolved operation (a running step), for logs.
pub fn begin_step( &mut self, name: &str, ) -> Result<(Seq, StepStart), DeterminismError>
pub fn begin_await(
&mut self,
name: &str,
) -> Result<(Seq, AwaitStart), DeterminismError>
pub fn begin_await( &mut self, name: &str, ) -> Result<(Seq, AwaitStart), DeterminismError>
Starts an async completion: like a step whose result comes from outside. The function that hands out the token runs as a step does.
pub fn awaiting(&mut self, seq: Seq) -> Option<RecordBuf>
pub fn awaiting(&mut self, seq: Seq) -> Option<RecordBuf>
The token function of async completion seq returned: the token for
its current attempt is out. Returns the Awaiting record to append.
pub fn await_attempt(&self, seq: Seq) -> Option<u32>
pub fn await_attempt(&self, seq: Seq) -> Option<u32>
The attempt an async completion’s current token names, if seq is
waiting for one.
pub fn step_retry(
&mut self,
seq: Seq,
retry_at_ms: u64,
error: Payload,
) -> Option<RecordBuf>
pub fn step_retry( &mut self, seq: Seq, retry_at_ms: u64, error: Payload, ) -> Option<RecordBuf>
A step attempt failed and will be retried. Returns the Attempt
record to append now; the shard arms the retry timer from it.
pub fn step_paused(&self, seq: Seq) -> bool
pub fn step_paused(&self, seq: Seq) -> bool
Whether step seq is paused (its retries ran out and no resume
has come).
pub fn step_pending(&self, seq: Seq) -> bool
pub fn step_pending(&self, seq: Seq) -> bool
Whether step seq still waits for its code to run it (not resolved,
for example by a cancellation).
pub fn is_paused(&self) -> bool
pub fn is_paused(&self) -> bool
Whether any of the run’s steps is paused, whether or not its code has reached it yet.
pub fn resume(&mut self, by: Option<Payload>) -> Vec<RecordBuf>
pub fn resume(&mut self, by: Option<Payload>) -> Vec<RecordBuf>
Resumes every paused step: each runs its next attempt at once, with
a fresh retry budget. Returns the Resume records to append, in
step order (none if nothing was paused).
pub fn step_attempt(&self, seq: Seq) -> Option<u32>
pub fn step_attempt(&self, seq: Seq) -> Option<u32>
The attempt number the next run of step seq will be.
pub fn heartbeat(&mut self, seq: Seq, payload: Payload) -> Option<RecordBuf>
pub fn heartbeat(&mut self, seq: Seq, payload: Payload) -> Option<RecordBuf>
A running step reported progress. Returns the Heartbeat record (the
host coalesces: only the latest per step is appended).
pub fn progress(&self, seq: Seq) -> Option<Payload>
pub fn progress(&self, seq: Seq) -> Option<Payload>
The latest progress step seq reported, in this life or a recorded
earlier one.
pub fn stream_open(
&mut self,
name: &str,
step: Option<Seq>,
) -> Result<StreamOpen, String>
pub fn stream_open( &mut self, name: &str, step: Option<Seq>, ) -> Result<StreamOpen, String>
Workflow code (step: None) or the function of the step at step
opens stream name. A stream belongs to whoever opens it first in
this life: workflow code, whose steps may append to it as well, or
one step, whose final result completes it.
pub fn stream_append(
&mut self,
name: &str,
step: Option<Seq>,
payload: Payload,
) -> Result<Option<RecordBuf>, String>
pub fn stream_append( &mut self, name: &str, step: Option<Seq>, payload: Payload, ) -> Result<Option<RecordBuf>, String>
Appends a chunk to stream name from workflow code (step: None)
or from the function of the step at step. Returns the Chunk
record to append, or none when there is nothing to append: workflow
code replaying an append its journal holds, or a step whose earlier
attempt completed the stream.
pub fn stream_close(
&mut self,
name: &str,
step: Option<Seq>,
) -> Result<Option<RecordBuf>, String>
pub fn stream_close( &mut self, name: &str, step: Option<Seq>, ) -> Result<Option<RecordBuf>, String>
Completes stream name from workflow code (step: None) or a step.
Returns the StreamEnd record to append, or none if the stream is
complete already (replay included).
pub fn stream_ends(&mut self, seq: Seq, status: Status) -> Vec<RecordBuf>
pub fn stream_ends(&mut self, seq: Seq, status: Status) -> Vec<RecordBuf>
The step at seq got its final result (status): the streams it
opened and did not close are complete. Returns their StreamEnd
records, to append just before the result’s record.
pub fn owns_streams(&self, seq: Seq) -> bool
pub fn owns_streams(&self, seq: Seq) -> bool
Whether some stream belongs to the step at seq in this life.
pub fn stream_len(&self, name: &str) -> Option<u64>
pub fn stream_len(&self, name: &str) -> Option<u64>
Chunks of stream name the journal and this life hold so far.
pub fn begin_sleep( &mut self, name: &str, fire_at_ms: u64, ) -> Result<(Seq, Arm), DeterminismError>
pub fn begin_wait( &mut self, name: &str, deadline_ms: u64, ) -> Result<(Seq, Arm), DeterminismError>
pub fn begin_child( &mut self, wtype: &str, id: &str, flags: u8, deadline_ms: u64, input: Payload, ) -> Result<(Seq, Arm), DeterminismError>
pub fn value(
&mut self,
kind: u8,
make: impl FnOnce() -> Payload,
) -> Result<(Seq, Payload, Option<RecordBuf>), DeterminismError>
pub fn value( &mut self, kind: u8, make: impl FnOnce() -> Payload, ) -> Result<(Seq, Payload, Option<RecordBuf>), DeterminismError>
A recorded nondeterministic value: the recorded one on replay, else
make()’s, returned together with the Value record to append.
pub fn now(
&mut self,
now_ms: u64,
) -> Result<(u64, Option<RecordBuf>), DeterminismError>
pub fn now( &mut self, now_ms: u64, ) -> Result<(u64, Option<RecordBuf>), DeterminismError>
Convenience for ctx.now(): Unix milliseconds as 8 little-endian bytes.
pub fn send(
&mut self,
target: &str,
name: &str,
payload: Payload,
) -> Result<(Seq, Option<RecordBuf>), DeterminismError>
pub fn send( &mut self, target: &str, name: &str, payload: Payload, ) -> Result<(Seq, Option<RecordBuf>), DeterminismError>
Sends a signal to another workflow once this record is durable.
pub fn set_attributes(
&mut self,
payload: Payload,
) -> Result<(Seq, Option<RecordBuf>), DeterminismError>
pub fn set_attributes( &mut self, payload: Payload, ) -> Result<(Seq, Option<RecordBuf>), DeterminismError>
Records search attributes (a JSON object).
pub fn patched(&mut self, id: &str) -> (bool, Option<RecordBuf>)
pub fn patched(&mut self, id: &str) -> (bool, Option<RecordBuf>)
ctx.patched(id): true for new runs and for running ones the first
time their code reaches this point after the patch was deployed;
false while replaying a journal that passed this point before.
Returns the Patch marker to append when the decision is new.
pub fn update_done(
&mut self,
ordinal: u64,
status: Status,
payload: Payload,
) -> Result<(Seq, Option<RecordBuf>), DeterminismError>
pub fn update_done( &mut self, ordinal: u64, status: Status, payload: Payload, ) -> Result<(Seq, Option<RecordBuf>), DeterminismError>
The handler for update ordinal returned. Returns the UpdateDone
record to append (none on replay).
pub fn offer_update(
&mut self,
token: u64,
name: Name,
id: Name,
payload: Payload,
)
pub fn offer_update( &mut self, token: u64, name: Name, id: Name, payload: Payload, )
Queues a new update request. It reaches the code at its turn, where the host runs its validator.
pub fn accept_update(
&mut self,
name: Name,
id: Name,
payload: Payload,
) -> (u64, RecordBuf)
pub fn accept_update( &mut self, name: Name, id: Name, payload: Payload, ) -> (u64, RecordBuf)
The validator accepted a live update delivered by next.
Returns its Update record, to append before starting the handler.
pub fn complete(&mut self, seq: Seq, completion: Completion) -> bool
pub fn complete(&mut self, seq: Seq, completion: Completion) -> bool
Reports a live completion. Ignored for operations that are not pending live (dropped, already resolved or replayed). Returns whether the completion was taken now.
pub fn is_live_pending(&self, seq: Seq) -> bool
pub fn is_live_pending(&self, seq: Seq) -> bool
Whether seq is pending a live result.
pub fn pending_kind(&self, seq: Seq) -> Option<OpKind>
pub fn cancellation_covers_current_operations(&self) -> bool
pub fn cancellation_covers_current_operations(&self) -> bool
A repeated request at the same code position has no new operation to cancel. A compensation step takes another sequence number and can be cancelled by a later request.
pub fn request_cancel(&mut self, reason: Payload)
pub fn request_cancel(&mut self, reason: Payload)
Queues cancellation. It reaches the code at its turn, like any delivery, so replay cancels exactly the same operations.
pub fn request_cancel_by(&mut self, reason: Payload, by: Option<Payload>)
pub fn request_cancel_by(&mut self, reason: Payload, by: Option<Payload>)
request_cancel, recording who asked on the
Cancel record (audit).
pub fn forget(&mut self, seq: Seq) -> Option<RecordBuf>
pub fn forget(&mut self, seq: Seq) -> Option<RecordBuf>
The code dropped the operation’s future (for example, the losing side
of a race). Its result will never be delivered. For a wait, returns
the Waited { Abandoned } record to append, so the shard stops
offering signals to it (none on replay: it is recorded).
pub fn next(&mut self) -> Next
pub fn next(&mut self) -> Next
The next delivery, if one may be made now. Call only when the code is quiescent; resolve the result, let the code run, then call again.
pub fn take_offered_updates(&mut self) -> Vec<u64>
pub fn take_offered_updates(&mut self) -> Vec<u64>
Update requests still queued (their callers are told the run ended).
pub fn stall_error(&self) -> Option<DeterminismError>
pub fn stall_error(&self) -> Option<DeterminismError>
Explains a stall the host has confirmed: the code is quiescent, no live work is pending, and the journal still has deliveries.
pub fn check_end(&self) -> Result<(), DeterminismError>
pub fn check_end(&self) -> Result<(), DeterminismError>
Checks that the code may end here: its journal has nothing left to deliver.