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}