Skip to main content

dex_sdk/
time_travel_options.rs

1// Copyright (c) 2026 Super Durable, Inc.
2//
3// Licensed under the Sustainable Use License 1.0.
4// You may not use this file except in compliance with the License.
5// See the LICENSE file in the repository root.
6//
7// SPDX-License-Identifier: LicenseRef-Sustainable-Use-1.0
8
9use std::time::SystemTime;
10
11use crate::{Step, StepExecutionId};
12
13#[derive(Clone, Debug)]
14/// Selects a historical point from which [`crate::Client::time_travel`] re-runs a Flow.
15///
16/// Time travel keeps the run ID and starts the next run attempt of that run.
17///
18/// Constructors identify exactly one time travel point. Builder methods add an audit reason and control
19/// whether writes are reapplied. Write reapplication defaults to enabled.
20pub struct TimeTravelOptions {
21    pub(crate) point: TimeTravelPoint,
22    pub(crate) reason: Option<String>,
23    pub(crate) skip_writes_reapply: bool,
24}
25
26#[derive(Clone, Debug)]
27pub(crate) enum TimeTravelPoint {
28    Beginning,
29    HistoryEventTime(SystemTime),
30    StepType(&'static str),
31    StepExecution(StepExecutionId, TimeTravelStepMethod),
32}
33
34#[derive(Clone, Copy, Debug)]
35/// Selects the Step method used as a Step execution time travel boundary.
36pub enum TimeTravelStepMethod {
37    /// Reruns WaitFor and everything after it.
38    WaitFor,
39    /// Keeps the WaitFor result and reruns Execute and everything after it.
40    Execute,
41}
42
43impl TimeTravelOptions {
44    /// Resumes before the first workflow-history event.
45    pub fn from_beginning() -> Self {
46        Self::new(TimeTravelPoint::Beginning)
47    }
48
49    /// Resumes at the last eligible history event at or before `event_time`.
50    pub fn from_history_event_time(event_time: SystemTime) -> Self {
51        Self::new(TimeTravelPoint::HistoryEventTime(event_time))
52    }
53
54    /// Resumes before the first execution of the selected Step type.
55    pub fn from_step<SomeStep: Step>(step: &SomeStep) -> Self {
56        Self::new(TimeTravelPoint::StepType(step.step_type()))
57    }
58
59    /// Resumes before one method of the exact Step execution identified by `step_execution`.
60    pub fn from_step_execution(
61        step_execution: StepExecutionId,
62        method: TimeTravelStepMethod,
63    ) -> Self {
64        Self::new(TimeTravelPoint::StepExecution(step_execution, method))
65    }
66
67    /// Adds an operator-facing reason recorded with time travel.
68    pub fn reason(mut self, reason: impl Into<String>) -> Self {
69        self.reason = Some(reason.into());
70        self
71    }
72
73    /// Controls whether later RPCs, Channel publications, and Attribute writes are skipped.
74    pub fn skip_writes_reapply(mut self, skip: bool) -> Self {
75        self.skip_writes_reapply = skip;
76        self
77    }
78
79    fn new(point: TimeTravelPoint) -> Self {
80        Self {
81            point,
82            reason: None,
83            skip_writes_reapply: false,
84        }
85    }
86}