Skip to main content

temporalio_client/
options_structs.rs

1use crate::{HttpConnectProxyOptions, RetryOptions, VERSION, callback_based};
2use http::Uri;
3use std::{collections::HashMap, time::Duration};
4use temporalio_common::{
5    data_converters::DataConverter,
6    protos::temporal::api::{
7        common::{
8            self,
9            v1::{Header, Payload, Payloads},
10        },
11        enums::v1::{
12            ArchivalState, HistoryEventFilterType, QueryRejectCondition, WorkflowIdConflictPolicy,
13            WorkflowIdReusePolicy,
14        },
15        replication::v1::ClusterReplicationConfig,
16        workflowservice::v1::RegisterNamespaceRequest,
17    },
18    telemetry::metrics::TemporalMeter,
19};
20use url::Url;
21
22/// Options for [crate::Connection::connect].
23#[derive(bon::Builder, Clone, Debug)]
24#[non_exhaustive]
25#[builder(start_fn = new, on(String, into), state_mod(vis = "pub"))]
26pub struct ConnectionOptions {
27    /// The server to connect to.
28    #[builder(start_fn, into)]
29    pub target: Url,
30    /// A human-readable string that can identify this process. Defaults to empty string.
31    #[builder(default)]
32    pub identity: String,
33    /// When set, this client will record metrics using the provided meter. The meter can be
34    /// obtained from [temporalio_common::telemetry::TelemetryInstance::get_temporal_metric_meter].
35    pub metrics_meter: Option<TemporalMeter>,
36    /// If specified, use TLS as configured by the [TlsOptions] struct. If this is set core will
37    /// attempt to use TLS when connecting to the Temporal server. Lang SDK is expected to pass any
38    /// certs or keys as bytes, loading them from disk itself if needed.
39    pub tls_options: Option<TlsOptions>,
40    /// If set, override the origin used when connecting. May be useful in rare situations where tls
41    /// verification needs to use a different name from what should be set as the `:authority`
42    /// header. If [TlsOptions::domain] is set, and this is not, this will be set to
43    /// `https://<domain>`, effectively making the `:authority` header consistent with the domain
44    /// override.
45    pub override_origin: Option<Uri>,
46    /// An API key to use for auth. If set, TLS will be enabled by default, but without any mTLS
47    /// specific settings.
48    pub api_key: Option<String>,
49    /// Retry configuration for the server client. Default is [RetryOptions::default]
50    #[builder(default)]
51    pub retry_options: RetryOptions,
52    /// If set, HTTP2 gRPC keep alive will be enabled.
53    /// To enable with default settings, use `.keep_alive(Some(ClientKeepAliveConfig::default()))`.
54    #[builder(required, default = Some(ClientKeepAliveOptions::default()))]
55    pub keep_alive: Option<ClientKeepAliveOptions>,
56    /// HTTP headers to include on every RPC call.
57    ///
58    /// These must be valid gRPC metadata keys, and must not be binary metadata keys (ending in
59    /// `-bin). To set binary headers, use [ConnectionOptions::binary_headers]. Invalid header keys
60    /// or values will cause an error to be returned when connecting.
61    pub headers: Option<HashMap<String, String>>,
62    /// HTTP headers to include on every RPC call as binary gRPC metadata (encoded as base64).
63    ///
64    /// These must be valid binary gRPC metadata keys (and end with a `-bin` suffix). Invalid
65    /// header keys will cause an error to be returned when connecting.
66    pub binary_headers: Option<HashMap<String, Vec<u8>>>,
67    /// HTTP CONNECT proxy to use for this client.
68    pub http_connect_proxy: Option<HttpConnectProxyOptions>,
69    /// If set true, error code labels will not be included on request failure metrics.
70    #[builder(default)]
71    pub disable_error_code_metric_tags: bool,
72    /// If set, all gRPC calls will be routed through the provided service.
73    pub service_override: Option<callback_based::CallbackBasedGrpcService>,
74
75    // Internal / Core-based SDK only options below =============================================
76    /// If set true, get_system_info will not be called upon connection.
77    #[builder(default)]
78    #[cfg_attr(feature = "core-based-sdk", builder(setters(vis = "pub")))]
79    pub(crate) skip_get_system_info: bool,
80    /// The name of the SDK being implemented on top of core. Is set as `client-name` header in
81    /// all RPC calls
82    #[builder(default = "temporal-rust".to_owned())]
83    #[cfg_attr(feature = "core-based-sdk", builder(setters(vis = "pub")))]
84    pub(crate) client_name: String,
85    // TODO [rust-sdk-branch]: SDK should set this to its version. Doing that probably easiest
86    // after adding proper client interceptors.
87    /// The version of the SDK being implemented on top of core. Is set as `client-version` header
88    /// in all RPC calls. The server decides if the client is supported based on this.
89    #[builder(default = VERSION.to_owned())]
90    #[cfg_attr(feature = "core-based-sdk", builder(setters(vis = "pub")))]
91    pub(crate) client_version: String,
92}
93
94// Setters/getters for fields that should only be touched by SDK implementers.
95#[cfg(feature = "core-based-sdk")]
96impl ConnectionOptions {
97    /// Set whether or not get_system_info will be called upon connection.
98    pub fn set_skip_get_system_info(&mut self, skip: bool) {
99        self.skip_get_system_info = skip;
100    }
101    /// Get whether or not get_system_info will be called upon connection.
102    pub fn get_skip_get_system_info(&self) -> bool {
103        self.skip_get_system_info
104    }
105    /// Get the name of the SDK being implemented on top of core.
106    pub fn get_client_name(&self) -> &str {
107        &self.client_name
108    }
109    /// Get the version of the SDK being implemented on top of core.
110    pub fn get_client_version(&self) -> &str {
111        &self.client_version
112    }
113}
114
115/// Options for [crate::Client::new].
116#[derive(Clone, Debug, bon::Builder)]
117#[non_exhaustive]
118#[builder(start_fn = new, on(String, into), state_mod(vis = "pub"))]
119pub struct ClientOptions {
120    /// The namespace this client will be bound to.
121    #[builder(start_fn)]
122    pub namespace: String,
123    /// The data converter used for serializing/deserializing payloads.
124    #[builder(default)]
125    pub data_converter: DataConverter,
126}
127
128/// Configuration options for TLS
129#[derive(Clone, Debug, Default)]
130pub struct TlsOptions {
131    /// Bytes representing the root CA certificate used by the server. If not set, and the server's
132    /// cert is issued by someone the operating system trusts, verification will still work (ex:
133    /// Cloud offering).
134    pub server_root_ca_cert: Option<Vec<u8>>,
135    /// Sets the domain name against which to verify the server's TLS certificate. If not provided,
136    /// the domain name will be extracted from the URL used to connect.
137    pub domain: Option<String>,
138    /// TLS info for the client. If specified, core will attempt to use mTLS.
139    pub client_tls_options: Option<ClientTlsOptions>,
140}
141
142/// If using mTLS, both the client cert and private key must be specified, this contains them.
143#[derive(Clone)]
144pub struct ClientTlsOptions {
145    /// The certificate for this client, encoded as PEM
146    pub client_cert: Vec<u8>,
147    /// The private key for this client, encoded as PEM
148    pub client_private_key: Vec<u8>,
149}
150
151/// Client keep alive configuration.
152#[derive(Clone, Debug)]
153pub struct ClientKeepAliveOptions {
154    /// Interval to send HTTP2 keep alive pings.
155    pub interval: Duration,
156    /// Timeout that the keep alive must be responded to within or the connection will be closed.
157    pub timeout: Duration,
158}
159
160impl Default for ClientKeepAliveOptions {
161    fn default() -> Self {
162        Self {
163            interval: Duration::from_secs(30),
164            timeout: Duration::from_secs(15),
165        }
166    }
167}
168
169impl std::fmt::Debug for ClientTlsOptions {
170    // Intentionally omit details here since they could leak a key if ever printed
171    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
172        write!(f, "ClientTlsOptions(..)")
173    }
174}
175
176/// Options for starting a workflow execution.
177#[derive(Debug, Clone, bon::Builder)]
178#[builder(start_fn = new, on(String, into))]
179#[non_exhaustive]
180pub struct WorkflowStartOptions {
181    /// The task queue to run the workflow on.
182    #[builder(start_fn)]
183    pub task_queue: String,
184
185    /// The workflow ID.
186    #[builder(start_fn)]
187    pub workflow_id: String,
188
189    /// Set the policy for reusing the workflow id
190    #[builder(default)]
191    pub id_reuse_policy: WorkflowIdReusePolicy,
192
193    /// Set the policy for how to resolve conflicts with running policies.
194    /// NOTE: This is ignored for child workflows.
195    #[builder(default)]
196    pub id_conflict_policy: WorkflowIdConflictPolicy,
197
198    /// Optionally set the execution timeout for the workflow
199    /// <https://docs.temporal.io/workflows/#workflow-execution-timeout>
200    pub execution_timeout: Option<Duration>,
201
202    /// Optionally indicates the default run timeout for a workflow run
203    pub run_timeout: Option<Duration>,
204
205    /// Optionally indicates the default task timeout for a workflow run
206    pub task_timeout: Option<Duration>,
207
208    /// Optionally set a cron schedule for the workflow
209    pub cron_schedule: Option<String>,
210
211    /// Optionally associate extra search attributes with a workflow
212    pub search_attributes: Option<HashMap<String, Payload>>,
213
214    /// Optionally enable Eager Workflow Start, a latency optimization using local workers
215    /// NOTE: Experimental
216    #[builder(default)]
217    pub enable_eager_workflow_start: bool,
218
219    /// Optionally set a retry policy for the workflow
220    pub retry_policy: Option<common::v1::RetryPolicy>,
221
222    /// If set, send a signal to the workflow atomically with start.
223    /// The workflow will receive this signal before its first task.
224    pub start_signal: Option<WorkflowStartSignal>,
225
226    /// Links to associate with the workflow. Ex: References to a nexus operation.
227    #[builder(default)]
228    pub links: Vec<common::v1::Link>,
229
230    /// Callbacks that will be invoked upon workflow completion. For, ex, completing nexus
231    /// operations.
232    #[builder(default)]
233    pub completion_callbacks: Vec<common::v1::Callback>,
234
235    /// Priority for the workflow. Defaults to all-inherited (empty).
236    #[builder(default)]
237    pub priority: Priority,
238
239    /// Headers to include with the start request.
240    pub header: Option<Header>,
241}
242
243/// A signal to send atomically when starting a workflow.
244/// Use with `WorkflowStartOptions::start_signal` to achieve signal-with-start behavior.
245#[derive(Debug, Clone, bon::Builder)]
246#[builder(start_fn = new, on(String, into))]
247#[non_exhaustive]
248pub struct WorkflowStartSignal {
249    /// Name of the signal to send.
250    #[builder(start_fn)]
251    pub signal_name: String,
252    /// Payload for the signal.
253    pub input: Option<Payloads>,
254    /// Headers for the signal.
255    pub header: Option<Header>,
256}
257
258pub use temporalio_common::Priority;
259
260/// Options for fetching workflow results
261#[derive(Debug, Clone, Copy, bon::Builder)]
262#[non_exhaustive]
263pub struct WorkflowGetResultOptions {
264    /// If true (the default), follows to the next workflow run in the execution chain while
265    /// retrieving results.
266    #[builder(default = true)]
267    pub follow_runs: bool,
268}
269impl Default for WorkflowGetResultOptions {
270    fn default() -> Self {
271        Self { follow_runs: true }
272    }
273}
274
275/// Options for starting a workflow update.
276#[derive(Debug, Clone, Default, bon::Builder)]
277#[non_exhaustive]
278pub struct WorkflowExecuteUpdateOptions {
279    /// Update ID for idempotency.
280    pub update_id: Option<String>,
281    /// Headers to include.
282    pub header: Option<Header>,
283}
284
285/// Options for sending a signal to a workflow.
286#[derive(Debug, Clone, Default, bon::Builder)]
287#[non_exhaustive]
288pub struct WorkflowSignalOptions {
289    /// Request ID for idempotency. If not provided, a UUID will be generated.
290    pub request_id: Option<String>,
291    /// Headers to include with the signal.
292    pub header: Option<Header>,
293}
294
295/// Options for querying a workflow.
296#[derive(Debug, Clone, Default, bon::Builder)]
297#[non_exhaustive]
298pub struct WorkflowQueryOptions {
299    /// Query reject condition. Determines when the query should be rejected
300    /// based on workflow state.
301    pub reject_condition: Option<QueryRejectCondition>,
302    /// Headers to include with the query.
303    pub header: Option<Header>,
304}
305
306/// Options for cancelling a workflow.
307#[derive(Debug, Clone, Default, bon::Builder)]
308#[builder(on(String, into))]
309#[non_exhaustive]
310pub struct WorkflowCancelOptions {
311    /// Reason for cancellation.
312    #[builder(default)]
313    pub reason: String,
314    /// Request ID for idempotency. If not provided, a UUID will be generated.
315    pub request_id: Option<String>,
316}
317
318/// Options for terminating a workflow.
319#[derive(Debug, Clone, Default, bon::Builder)]
320#[builder(on(String, into))]
321#[non_exhaustive]
322pub struct WorkflowTerminateOptions {
323    /// Reason for termination.
324    #[builder(default)]
325    pub reason: String,
326    /// Additional details to include with the termination.
327    pub details: Option<Payloads>,
328}
329
330/// Options for describing a workflow.
331#[derive(Debug, Clone, Default, bon::Builder)]
332#[non_exhaustive]
333pub struct WorkflowDescribeOptions {}
334
335/// Default workflow execution retention for a Namespace is 3 days
336const DEFAULT_WORKFLOW_EXECUTION_RETENTION_PERIOD: Duration = Duration::from_secs(60 * 60 * 24 * 3);
337
338/// Helper struct for `register_namespace`.
339#[derive(Clone, Debug, bon::Builder)]
340#[builder(on(String, into))]
341pub struct RegisterNamespaceOptions {
342    /// Name (required)
343    pub namespace: String,
344    /// Description (required)
345    pub description: String,
346    /// Owner's email
347    #[builder(default)]
348    pub owner_email: String,
349    /// Workflow execution retention period
350    #[builder(default = DEFAULT_WORKFLOW_EXECUTION_RETENTION_PERIOD)]
351    pub workflow_execution_retention_period: Duration,
352    /// Cluster settings
353    #[builder(default)]
354    pub clusters: Vec<ClusterReplicationConfig>,
355    /// Active cluster name
356    #[builder(default)]
357    pub active_cluster_name: String,
358    /// Custom Data
359    #[builder(default)]
360    pub data: HashMap<String, String>,
361    /// Security Token
362    #[builder(default)]
363    pub security_token: String,
364    /// Global namespace
365    #[builder(default)]
366    pub is_global_namespace: bool,
367    /// History Archival setting
368    #[builder(default = ArchivalState::Unspecified)]
369    pub history_archival_state: ArchivalState,
370    /// History Archival uri
371    #[builder(default)]
372    pub history_archival_uri: String,
373    /// Visibility Archival setting
374    #[builder(default = ArchivalState::Unspecified)]
375    pub visibility_archival_state: ArchivalState,
376    /// Visibility Archival uri
377    #[builder(default)]
378    pub visibility_archival_uri: String,
379}
380
381impl From<RegisterNamespaceOptions> for RegisterNamespaceRequest {
382    fn from(val: RegisterNamespaceOptions) -> Self {
383        RegisterNamespaceRequest {
384            namespace: val.namespace,
385            description: val.description,
386            owner_email: val.owner_email,
387            workflow_execution_retention_period: val
388                .workflow_execution_retention_period
389                .try_into()
390                .ok(),
391            clusters: val.clusters,
392            active_cluster_name: val.active_cluster_name,
393            data: val.data,
394            security_token: val.security_token,
395            is_global_namespace: val.is_global_namespace,
396            history_archival_state: val.history_archival_state as i32,
397            history_archival_uri: val.history_archival_uri,
398            visibility_archival_state: val.visibility_archival_state as i32,
399            visibility_archival_uri: val.visibility_archival_uri,
400        }
401    }
402}
403
404/// Options for fetching workflow history.
405#[derive(Debug, Clone, Default, bon::Builder)]
406#[non_exhaustive]
407pub struct WorkflowFetchHistoryOptions {
408    /// Whether to skip archival.
409    #[builder(default)]
410    pub skip_archival: bool,
411    /// If set true, the fetch will wait for a new event before returning.
412    #[builder(default)]
413    pub wait_new_event: bool,
414    /// Specifies which kind of events will be retrieved. Defaults to all events.
415    #[builder(default = HistoryEventFilterType::AllEvent)]
416    pub event_filter_type: HistoryEventFilterType,
417}
418
419/// Which lifecycle stage to wait for when starting an update.
420#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
421pub enum WorkflowUpdateWaitStage {
422    /// This stage is reached when the server receives the update to process.
423    /// This is currently an invalid value on start.
424    Admitted,
425    /// Wait until the update is accepted by the workflow (validator passed).
426    #[default]
427    Accepted,
428    /// Wait until the update has completed.
429    Completed,
430}
431
432/// Options for starting an update without waiting for completion.
433#[derive(Debug, Clone, Default, bon::Builder)]
434#[non_exhaustive]
435pub struct WorkflowStartUpdateOptions {
436    /// Update ID for idempotency. If not provided, a UUID will be generated.
437    pub update_id: Option<String>,
438    /// Headers to include with the update.
439    pub header: Option<Header>,
440    /// The lifecycle stage to wait for before returning the handle.
441    #[builder(default)]
442    pub wait_for_stage: WorkflowUpdateWaitStage,
443}
444
445/// Options for listing workflows.
446#[derive(Debug, Clone, Default, bon::Builder)]
447#[non_exhaustive]
448pub struct WorkflowListOptions {
449    /// Maximum number of workflows to return.
450    /// If not specified, returns all matching workflows.
451    pub limit: Option<usize>,
452}
453
454/// Options for counting workflows.
455#[derive(Debug, Clone, Default, bon::Builder)]
456#[non_exhaustive]
457pub struct WorkflowCountOptions {}