Skip to main content

Client

Struct Client 

Source
pub struct Client { /* private fields */ }
Expand description

A registry-less, out-of-process handle over the system database.

Unlike DurableEngine, a Client holds no workflow registry and runs nothing: it enqueues workflows for executors to claim, sends messages, reads events, and queries workflow state. It is the producer/observer half of the split between enqueueing work and executing it.

use durare::{Client, PostgresProvider, WorkflowOptions};
use std::sync::Arc;

let provider = Arc::new(PostgresProvider::connect("postgres://localhost/app").await?);
let client = Client::new(provider);

// Enqueue for an executor fleet elsewhere to run; observe from here.
let handle = client
    .enqueue::<_, String>("orders", "process_order", "1001".to_string(), WorkflowOptions::default())
    .await?;
println!("state: {}", handle.get_status().await?.status);

Implementations§

Source§

impl Client

Source

pub fn new(provider: Arc<dyn StateProvider>) -> Self

Build a client over an existing StateProvider (e.g. a PostgresProvider connected to the system database). The database must already be initialized by the application.

Enqueued work is left version-agnostic (empty application version), so any executor claims it regardless of its version. Use with_app_version to gate it to one version.

Source

pub fn with_app_version(self, version: impl Into<String>) -> Self

Stamp enqueued workflows with this application version, so only an executor of the same version claims them (version-gated dispatch).

Source

pub fn provider(&self) -> &Arc<dyn StateProvider>

The underlying state provider.

Source

pub fn debouncer(&self, target_workflow: &str) -> DebouncerClient<'_>

Debounce a target workflow from out of process — coalesce rapid repeated triggers (grouped by key) into a single delayed run with the latest input. A launched engine elsewhere (which auto-registers the internal debouncer and has the target registered) executes the coalesced run.

Source

pub async fn enqueue<I, O>( &self, queue_name: &str, workflow_name: &str, input: I, opts: WorkflowOptions, ) -> Result<WorkflowHandle<O>>
where I: Serialize,

Enqueue workflow_name on queue_name for an executor to claim and run. The workflow need not be registered in this process. Returns a polling WorkflowHandle over the result.

The row is persisted ENQUEUED (or DELAYED when opts.delay is set); opts.queue is ignored — the queue is the first argument.

§Errors

Error::QueueDeduplicated if opts.dedup_id collides with an active workflow on the queue (under the default Reject policy); an application error for an empty queue or workflow name, a partition key combined with a deduplication id, or a deduplication policy without a deduplication id.

Source

pub async fn send<T: Serialize>( &self, destination_id: &str, message: T, topic: &str, ) -> Result<()>

Send a message to a workflow (e.g. to nudge one waiting in DurableContext::recv). Not durable — there is no calling workflow to checkpoint into.

Source

pub async fn send_with_idempotency_key<T: Serialize>( &self, destination_id: &str, message: T, topic: &str, idempotency_key: &str, ) -> Result<()>

Like send but idempotent: the message is delivered at most once for a given idempotency_key and destination, so an out-of-process producer that retries after a transient failure never double-delivers. Distinct keys each deliver.

Source

pub async fn get_event<T: DeserializeOwned>( &self, target_workflow_id: &str, key: &str, timeout: Duration, ) -> Result<Option<T>>

Read event key of a workflow, waiting up to timeout for it to be set. Returns None on timeout.

Source

pub async fn retrieve_workflow<O>(&self, id: &str) -> Result<WorkflowHandle<O>>

A polling WorkflowHandle for an existing workflow. Errors if no workflow exists under id.

Source

pub async fn list_workflows( &self, filter: &ListFilter, ) -> Result<Vec<WorkflowStatus>>

List workflows matching filter.

Source

pub async fn get_workflow_steps( &self, workflow_id: &str, ) -> Result<Vec<StepInfo>>

The recorded steps of a workflow, ordered by step id.

Source

pub async fn cancel_workflow(&self, id: &str) -> Result<()>

Cancel a workflow: a non-terminal one is set CANCELLED and removed from its queue; a running workflow stops at its next step.

Source

pub async fn cancel_workflows(&self, ids: &[String]) -> Result<()>

Cancel many workflows in one round-trip. Missing or already-terminal ids are skipped; an empty slice is a no-op.

Source

pub async fn delete_workflows( &self, ids: &[String], delete_children: bool, ) -> Result<()>

Delete many workflows and (via ON DELETE CASCADE) their step / event / stream rows. When delete_children, every descendant by parent_workflow_id is removed too. Missing ids are skipped.

Source

pub async fn resume_workflow<O>(&self, id: &str) -> Result<WorkflowHandle<O>>

Resume a cancelled (or otherwise non-terminal) workflow: re-queue it onto the internal queue so a dispatcher on a live engine re-runs it from its checkpoints. Returns a polling handle. Resuming an already-completed workflow is a no-op: the handle simply reads its recorded outcome. A missing id is a typed Error::NonExistentWorkflow.

Source

pub async fn resume_workflow_on<O>( &self, id: &str, queue: &str, ) -> Result<WorkflowHandle<O>>

Like resume_workflow but re-queues onto queue instead of the internal queue, so the resumed run competes under that queue’s concurrency and rate limits.

Source

pub async fn resume_workflows<O>( &self, ids: &[String], ) -> Result<Vec<WorkflowHandle<O>>>

Resume many workflows in one round-trip onto the internal queue. A polling handle is returned for every id that exists, in input order — an already-terminal workflow is a no-op whose handle reads its recorded outcome; missing ids yield no handle (and no error).

Source

pub async fn resume_workflows_on<O>( &self, ids: &[String], queue: &str, ) -> Result<Vec<WorkflowHandle<O>>>

Like resume_workflows but re-queues onto queue instead of the internal queue.

Source

pub async fn fork_workflow<O>( &self, original_id: &str, start_step: i32, opts: WorkflowOptions, ) -> Result<WorkflowHandle<O>>

Fork a workflow from start_step: a new workflow reuses the original’s checkpoints for steps < start_step and re-executes from there. Enqueued onto opts.queue (the internal queue when unset) with opts.partition_key for a dispatcher on a live engine to run; returns a polling handle. The new id comes from opts.workflow_id or is generated. opts.app_version overrides the version stamped on the fork; unset, the fork inherits the original’s, staying runnable by the executors that could run the original.

Source

pub async fn set_workflow_delay( &self, id: &str, delay: Duration, ) -> Result<bool>

Reschedule a DELAYED workflow to become eligible delay from now. A running executor’s dispatcher promotes it once due. Returns false (no error) if no DELAYED row matched.

Source

pub async fn set_workflow_delay_until( &self, id: &str, at: DateTime<Utc>, ) -> Result<bool>

Like set_workflow_delay but with an absolute instant rather than an offset from now.

Source

pub async fn read_stream<T: DeserializeOwned>( &self, workflow_id: &str, key: &str, ) -> Result<(Vec<T>, bool)>

Read a workflow’s stream key in order, blocking until the stream closes or the producing workflow goes inactive. Returns the values and whether the stream is closed.

Source

pub async fn read_stream_snapshot<T: DeserializeOwned>( &self, workflow_id: &str, key: &str, from_offset: i32, ) -> Result<(Vec<T>, bool)>

Read the currently-available values of stream key from from_offset without blocking. Returns the values in order and whether the stream is closed. Pass the count read so far as the next from_offset to poll.

Source

pub fn read_stream_values<T: DeserializeOwned + 'static>( &self, workflow_id: &str, key: &str, ) -> impl Stream<Item = Result<T>> + '_

Read a workflow’s stream key as an asynchronous Stream, yielding each value in order as it is committed — the incremental counterpart to read_stream, which blocks and returns the whole stream at once. The stream ends when the producer closes it or goes inactive; a decode or backend failure (or a missing workflow) is the final Err item. Consume it with StreamExt::next.

Source

pub async fn list_application_versions(&self) -> Result<Vec<VersionInfo>>

Every registered application version, newest first.

Source

pub async fn get_latest_application_version( &self, ) -> Result<Option<VersionInfo>>

The latest registered application version, or None if none are registered.

Source

pub async fn set_latest_application_version( &self, version_name: &str, ) -> Result<bool>

Mark a registered version as latest (bumps its version_timestamp). Returns whether a matching version existed; rejects an empty name.

Source

pub async fn create_schedule( &self, schedule_name: &str, workflow_name: &str, cron: &str, opts: ScheduleOptions, ) -> Result<()>

Create a durable cron schedule firing workflow_name on each tick of cron. Validates the cron and timezone, but — unlike the engine — does not require the workflow to be registered here: the executor that runs the schedule owns that. Errors on an invalid spec or a duplicate name.

Source

pub async fn apply_schedules(&self, schedules: Vec<ApplySchedule>) -> Result<()>

Create or replace each schedule by name, in one call (validated whole before any write). Like create_schedule, the workflow need not be registered here.

Source

pub async fn get_schedule( &self, schedule_name: &str, ) -> Result<Option<WorkflowSchedule>>

The schedule named schedule_name, or None if there is none.

Source

pub async fn list_schedules( &self, filter: &ScheduleFilter, ) -> Result<Vec<WorkflowSchedule>>

All schedules matching filter (a default filter returns every schedule), ordered by name.

Source

pub async fn pause_schedule(&self, schedule_name: &str) -> Result<bool>

Pause a schedule so it stops firing. Returns whether a schedule matched.

Source

pub async fn resume_schedule(&self, schedule_name: &str) -> Result<bool>

Resume a paused schedule. Returns whether a schedule matched.

Source

pub async fn delete_schedule(&self, schedule_name: &str) -> Result<bool>

Delete a schedule. Returns whether a schedule was removed.

Source

pub async fn trigger_schedule<O>( &self, schedule_name: &str, ) -> Result<WorkflowHandle<O>>

Fire a schedule’s workflow once, immediately, for an engine to run. Returns a polling WorkflowHandle over the run. The tick uses a distinct sched-{name}-trigger-{time} id, so it never collides with or replaces a regular cron tick.

A schedule with a queue routes the run there; a direct (queue-less) schedule routes to the internal queue — the client runs nothing, so a live engine’s always-on internal dispatcher executes it.

Source

pub async fn backfill_schedule( &self, schedule_name: &str, start: DateTime<Utc>, end: DateTime<Utc>, ) -> Result<Vec<String>>

Enqueue a schedule’s ticks for every cron instant in (start, end) (both bounds exclusive) for an engine to run, under the same deterministic per-tick ids the live loop uses — so a tick that already ran is skipped, not duplicated. Returns the id of every tick in the range, in order (including skipped ones).

Like trigger_schedule, a direct (queue-less) schedule routes its ticks to the internal queue.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more