Skip to main content

temporalio_workflow/
workflows.rs

1//! Functionality related to defining and interacting with workflows
2//!
3//! This module contains traits and types for implementing workflows using the
4//! `#[workflow]` and `#[workflow_methods]` macros.
5//!
6//! Example usage:
7//! ```
8//! use temporalio_macros::{workflow, workflow_methods};
9//! use temporalio_workflow::{
10//!     SyncWorkflowContext, WorkflowContext, WorkflowContextView, WorkflowResult,
11//! };
12//!
13//! #[workflow]
14//! pub struct MyWorkflow {
15//!     counter: u32,
16//! }
17//!
18//! #[workflow_methods]
19//! impl MyWorkflow {
20//!     #[init]
21//!     pub fn new(ctx: &WorkflowContextView, input: String) -> Self {
22//!         Self { counter: 0 }
23//!     }
24//!
25//!     // Async run method uses ctx.state() for reading
26//!     #[run]
27//!     pub async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<String> {
28//!         let counter = ctx.state(|s| s.counter);
29//!         Ok(format!("Done with counter: {}", counter))
30//!     }
31//!
32//!     // Sync signals use &mut self for direct mutations
33//!     #[signal]
34//!     pub fn increment(&mut self, ctx: &mut SyncWorkflowContext<Self>, amount: u32) {
35//!         self.counter += amount;
36//!     }
37//!
38//!     // Queries use &self with read-only context
39//!     #[query]
40//!     pub fn get_counter(&self, ctx: &WorkflowContextView) -> u32 {
41//!         self.counter
42//!     }
43//! }
44//! ```
45
46/// Deterministic `select!` for use in Temporal workflows.
47///
48/// Polls branches in declaration order (top to bottom), ensuring deterministic
49/// behavior across workflow replays. Delegates to [`futures_util::select_biased!`].
50///
51/// All workflow futures (timers, activities, child workflows, etc.) implement
52/// `FusedFuture`, so they can be stored in variables and passed to `select!`
53/// without needing `.fuse()`.
54///
55/// # Example
56///
57/// ```ignore
58/// use temporalio_sdk::workflows::select;
59/// use temporalio_sdk::WorkflowContext;
60/// use std::time::Duration;
61///
62/// # async fn hidden(ctx: &mut WorkflowContext<()>) {
63/// select! {
64///     _ = ctx.timer(Duration::from_secs(60)) => { /* timer fired */ }
65///     reason = ctx.cancelled() => { /* cancelled */ }
66/// };
67/// # }
68/// ```
69#[doc(inline)]
70pub use crate::__temporal_select as select;
71
72/// Deterministic `join!` for use in Temporal workflows.
73///
74/// Polls all futures concurrently to completion in declaration order,
75/// ensuring deterministic behavior across workflow replays. Delegates
76/// to [`futures_util::join!`].
77///
78/// # Example
79///
80/// ```ignore
81/// use temporalio_sdk::workflows::join;
82///
83/// # async fn hidden() {
84/// let future_a = async { 1 };
85/// let future_b = async { 2 };
86/// let (a, b) = join!(future_a, future_b);
87/// # }
88/// ```
89#[doc(inline)]
90pub use crate::__temporal_join as join;
91
92use crate::runtime::SdkGuardedFuture;
93use futures_util::FutureExt;
94
95pub use crate::runtime::entry::{
96    ExecutableAsyncSignal, ExecutableAsyncUpdate, ExecutableQuery, ExecutableSyncSignal,
97    ExecutableSyncUpdate, WorkflowError, WorkflowImplementation, serialize_result,
98};
99
100/// Deterministic `join_all` for use in Temporal workflows.
101///
102/// Polls a collection of futures concurrently to completion in declaration order,
103/// returning a `Vec` of their results.
104///
105/// # Example
106///
107/// ```ignore
108/// use temporalio_sdk::workflows::join_all;
109/// use temporalio_sdk::WorkflowContext;
110/// use std::time::Duration;
111///
112/// # async fn hidden(ctx: &mut WorkflowContext<()>) {
113/// let timers = vec![
114///     ctx.timer(Duration::from_secs(1)),
115///     ctx.timer(Duration::from_secs(2)),
116/// ];
117/// let results = join_all(timers).await;
118/// # }
119/// ```
120pub fn join_all<I>(iter: I) -> JoinAll<I::Item>
121where
122    I: IntoIterator,
123    I::Item: std::future::Future,
124{
125    JoinAll(SdkGuardedFuture(futures_util::future::join_all(iter)))
126}
127
128/// Future returned by [`join_all`].
129pub struct JoinAll<F: std::future::Future>(SdkGuardedFuture<futures_util::future::JoinAll<F>>);
130
131impl<F: std::future::Future> std::future::Future for JoinAll<F> {
132    type Output = Vec<F::Output>;
133
134    fn poll(
135        mut self: std::pin::Pin<&mut Self>,
136        cx: &mut std::task::Context<'_>,
137    ) -> std::task::Poll<Self::Output> {
138        self.0.poll_unpin(cx)
139    }
140}