Skip to main content

sayiir_runtime/runner/
ext.rs

1use super::WorkflowRunner;
2use crate::error::RuntimeError;
3use crate::runner::in_process::InProcessRunner;
4use sayiir_core::codec::sealed;
5use sayiir_core::codec::{Codec, EnvelopeCodec};
6use sayiir_core::workflow::{Workflow, WorkflowStatus};
7
8/// Extension trait providing convenience methods on [`Workflow`].
9///
10/// # Caveats
11///
12/// This trait uses [`InProcessRunner`] under the hood, which means:
13/// - **No checkpointing** — workflow state is not persisted between steps.
14/// - **No crash recovery** — if the process dies, progress is lost.
15/// - **No distributed execution** — everything runs in the current process.
16///
17/// For production use with durability guarantees, use a [`WorkflowRunner`]
18/// backed by a persistence backend (e.g. `PostgreSQL`) instead.
19pub trait WorkflowRunExt<C, Input, M> {
20    /// Run the workflow once in-process without persistence.
21    ///
22    /// Uses [`InProcessRunner`] internally — no backend, no instance ID.
23    /// Ideal for quick testing and simple scripts.
24    ///
25    /// # Example
26    ///
27    /// ```rust,no_run
28    /// # use sayiir_runtime::prelude::*;
29    /// # use sayiir_core::error::BoxError;
30    /// # async fn example() -> Result<(), BoxError> {
31    /// let ctx = WorkflowContext::new("demo", std::sync::Arc::new(JsonCodec), std::sync::Arc::new(()));
32    /// let workflow = WorkflowBuilder::new(ctx)
33    ///     .then("greet", |name: String| async move { Ok(format!("Hello, {name}!")) })
34    ///     .build()?;
35    ///
36    /// let status = workflow.run_once("World".to_string()).await?;
37    /// # Ok(())
38    /// # }
39    /// ```
40    fn run_once(
41        &self,
42        input: Input,
43    ) -> impl std::future::Future<Output = Result<WorkflowStatus, RuntimeError>> + Send + '_
44    where
45        Input: Send + 'static,
46        M: Send + Sync + 'static,
47        C: Codec + EnvelopeCodec + sealed::EncodeValue<Input>;
48}
49
50impl<C, Input, M> WorkflowRunExt<C, Input, M> for Workflow<C, Input, M> {
51    fn run_once(
52        &self,
53        input: Input,
54    ) -> impl std::future::Future<Output = Result<WorkflowStatus, RuntimeError>> + Send + '_
55    where
56        Input: Send + 'static,
57        M: Send + Sync + 'static,
58        C: Codec + EnvelopeCodec + sealed::EncodeValue<Input>,
59    {
60        InProcessRunner.run(self, input)
61    }
62}