@temporalio/core-bridge 1.5.2 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +255 -48
- package/package.json +4 -4
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/releases/x86_64-apple-darwin/index.node +0 -0
- package/releases/x86_64-pc-windows-msvc/index.node +0 -0
- package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
- package/sdk-core/.buildkite/pipeline.yml +1 -3
- package/sdk-core/.cargo/config.toml +5 -2
- package/sdk-core/.github/workflows/heavy.yml +28 -0
- package/sdk-core/Cargo.toml +1 -1
- package/sdk-core/README.md +9 -5
- package/sdk-core/client/src/lib.rs +211 -36
- package/sdk-core/client/src/raw.rs +1 -1
- package/sdk-core/client/src/retry.rs +32 -20
- package/sdk-core/core/Cargo.toml +23 -9
- package/sdk-core/core/src/abstractions.rs +11 -0
- package/sdk-core/core/src/core_tests/activity_tasks.rs +6 -5
- package/sdk-core/core/src/core_tests/local_activities.rs +263 -22
- package/sdk-core/core/src/core_tests/queries.rs +2 -2
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +249 -5
- package/sdk-core/core/src/ephemeral_server/mod.rs +5 -6
- package/sdk-core/core/src/lib.rs +2 -0
- package/sdk-core/core/src/protosext/mod.rs +1 -1
- package/sdk-core/core/src/telemetry/log_export.rs +1 -1
- package/sdk-core/core/src/telemetry/mod.rs +23 -8
- package/sdk-core/core/src/test_help/mod.rs +8 -1
- package/sdk-core/core/src/worker/activities/local_activities.rs +259 -125
- package/sdk-core/core/src/worker/activities.rs +3 -2
- package/sdk-core/core/src/worker/mod.rs +53 -26
- package/sdk-core/core/src/worker/workflow/bridge.rs +1 -3
- package/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -5
- package/sdk-core/core/src/worker/workflow/history_update.rs +835 -277
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +9 -17
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +3 -5
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +3 -5
- package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +73 -51
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +3 -3
- package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +4 -4
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +3 -5
- package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +6 -7
- package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +2 -2
- package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +4 -4
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +6 -17
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +89 -58
- package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +4 -7
- package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +21 -9
- package/sdk-core/core/src/worker/workflow/managed_run.rs +1021 -360
- package/sdk-core/core/src/worker/workflow/mod.rs +306 -346
- package/sdk-core/core/src/worker/workflow/run_cache.rs +29 -53
- package/sdk-core/core/src/worker/workflow/wft_extraction.rs +125 -0
- package/sdk-core/core/src/worker/workflow/wft_poller.rs +1 -4
- package/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +115 -0
- package/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +24 -0
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +444 -714
- package/sdk-core/core-api/Cargo.toml +2 -0
- package/sdk-core/core-api/src/errors.rs +1 -34
- package/sdk-core/core-api/src/lib.rs +6 -2
- package/sdk-core/core-api/src/worker.rs +14 -1
- package/sdk-core/etc/deps.svg +115 -140
- package/sdk-core/etc/regen-depgraph.sh +5 -0
- package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +6 -6
- package/sdk-core/fsm/rustfsm_trait/src/lib.rs +7 -3
- package/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
- package/sdk-core/protos/api_upstream/Makefile +5 -5
- package/sdk-core/protos/api_upstream/build/go.mod +7 -0
- package/sdk-core/protos/api_upstream/build/go.sum +5 -0
- package/sdk-core/protos/api_upstream/build/tools.go +29 -0
- package/sdk-core/protos/api_upstream/go.mod +6 -0
- package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +9 -2
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +12 -19
- package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +3 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +3 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +3 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +3 -3
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +20 -2
- package/sdk-core/protos/api_upstream/temporal/api/{update/v1/message.proto → enums/v1/interaction_type.proto} +11 -18
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +2 -13
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +13 -19
- package/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +87 -0
- package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +13 -8
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +2 -2
- package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +2 -0
- package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +2 -2
- package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +2 -2
- package/sdk-core/sdk/Cargo.toml +4 -3
- package/sdk-core/sdk/src/lib.rs +87 -21
- package/sdk-core/sdk/src/workflow_future.rs +7 -12
- package/sdk-core/sdk-core-protos/Cargo.toml +5 -2
- package/sdk-core/sdk-core-protos/build.rs +36 -2
- package/sdk-core/sdk-core-protos/src/history_builder.rs +26 -19
- package/sdk-core/sdk-core-protos/src/history_info.rs +4 -0
- package/sdk-core/sdk-core-protos/src/lib.rs +78 -34
- package/sdk-core/sdk-core-protos/src/task_token.rs +12 -2
- package/sdk-core/test-utils/Cargo.toml +3 -1
- package/sdk-core/test-utils/src/histfetch.rs +1 -1
- package/sdk-core/test-utils/src/lib.rs +50 -18
- package/sdk-core/test-utils/src/wf_input_saver.rs +50 -0
- package/sdk-core/test-utils/src/workflows.rs +29 -0
- package/sdk-core/tests/fuzzy_workflow.rs +130 -0
- package/sdk-core/tests/{load_tests.rs → heavy_tests.rs} +114 -7
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +5 -2
- package/sdk-core/tests/integ_tests/metrics_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/polling_tests.rs +1 -39
- package/sdk-core/tests/integ_tests/queries_tests.rs +2 -127
- package/sdk-core/tests/integ_tests/visibility_tests.rs +52 -5
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +74 -1
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +5 -13
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +2 -10
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +69 -197
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +4 -28
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +12 -7
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +14 -14
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +3 -19
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +3 -19
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests.rs +5 -6
- package/sdk-core/tests/main.rs +2 -12
- package/sdk-core/tests/runner.rs +71 -34
- package/sdk-core/tests/wf_input_replay.rs +32 -0
- package/sdk-core/bridge-ffi/Cargo.toml +0 -24
- package/sdk-core/bridge-ffi/LICENSE.txt +0 -23
- package/sdk-core/bridge-ffi/build.rs +0 -25
- package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +0 -224
- package/sdk-core/bridge-ffi/src/lib.rs +0 -746
- package/sdk-core/bridge-ffi/src/wrappers.rs +0 -221
- package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +0 -210
- package/sdk-core/sdk/src/conversions.rs +0 -8
|
@@ -184,8 +184,7 @@ impl TryFrom<HistoryEvent> for ActivityMachineEvents {
|
|
|
184
184
|
Self::ActivityTaskCompleted(attrs)
|
|
185
185
|
} else {
|
|
186
186
|
return Err(WFMachinesError::Fatal(format!(
|
|
187
|
-
"Activity completion attributes were unset: {}"
|
|
188
|
-
e
|
|
187
|
+
"Activity completion attributes were unset: {e}"
|
|
189
188
|
)));
|
|
190
189
|
}
|
|
191
190
|
}
|
|
@@ -196,8 +195,7 @@ impl TryFrom<HistoryEvent> for ActivityMachineEvents {
|
|
|
196
195
|
Self::ActivityTaskFailed(attrs)
|
|
197
196
|
} else {
|
|
198
197
|
return Err(WFMachinesError::Fatal(format!(
|
|
199
|
-
"Activity failure attributes were unset: {}"
|
|
200
|
-
e
|
|
198
|
+
"Activity failure attributes were unset: {e}"
|
|
201
199
|
)));
|
|
202
200
|
}
|
|
203
201
|
}
|
|
@@ -208,8 +206,7 @@ impl TryFrom<HistoryEvent> for ActivityMachineEvents {
|
|
|
208
206
|
Self::ActivityTaskTimedOut(attrs)
|
|
209
207
|
} else {
|
|
210
208
|
return Err(WFMachinesError::Fatal(format!(
|
|
211
|
-
"Activity timeout attributes were unset: {}"
|
|
212
|
-
e
|
|
209
|
+
"Activity timeout attributes were unset: {e}"
|
|
213
210
|
)));
|
|
214
211
|
}
|
|
215
212
|
}
|
|
@@ -221,15 +218,13 @@ impl TryFrom<HistoryEvent> for ActivityMachineEvents {
|
|
|
221
218
|
Self::ActivityTaskCanceled(attrs)
|
|
222
219
|
} else {
|
|
223
220
|
return Err(WFMachinesError::Fatal(format!(
|
|
224
|
-
"Activity cancellation attributes were unset: {}"
|
|
225
|
-
e
|
|
221
|
+
"Activity cancellation attributes were unset: {e}"
|
|
226
222
|
)));
|
|
227
223
|
}
|
|
228
224
|
}
|
|
229
225
|
_ => {
|
|
230
226
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
231
|
-
"Activity machine does not handle this event: {}"
|
|
232
|
-
e
|
|
227
|
+
"Activity machine does not handle this event: {e}"
|
|
233
228
|
)))
|
|
234
229
|
}
|
|
235
230
|
})
|
|
@@ -339,7 +334,7 @@ impl Cancellable for ActivityMachine {
|
|
|
339
334
|
)
|
|
340
335
|
.into()]
|
|
341
336
|
}
|
|
342
|
-
x => panic!("Invalid cancel event response {:?}"
|
|
337
|
+
x => panic!("Invalid cancel event response {x:?}"),
|
|
343
338
|
})
|
|
344
339
|
.collect();
|
|
345
340
|
Ok(res)
|
|
@@ -648,8 +643,7 @@ impl Canceled {
|
|
|
648
643
|
} else {
|
|
649
644
|
TransitionResult::Err(WFMachinesError::Nondeterminism(format!(
|
|
650
645
|
"Non-Abandon cancel mode activities cannot be started after being cancelled. \
|
|
651
|
-
Seq: {:?}"
|
|
652
|
-
seq_num
|
|
646
|
+
Seq: {seq_num:?}"
|
|
653
647
|
)))
|
|
654
648
|
}
|
|
655
649
|
}
|
|
@@ -663,8 +657,7 @@ impl Canceled {
|
|
|
663
657
|
TransitionResult::default()
|
|
664
658
|
} else {
|
|
665
659
|
TransitionResult::Err(WFMachinesError::Nondeterminism(format!(
|
|
666
|
-
"Non-Abandon cancel mode activities cannot be completed after being cancelled: {:?}"
|
|
667
|
-
attrs
|
|
660
|
+
"Non-Abandon cancel mode activities cannot be completed after being cancelled: {attrs:?}"
|
|
668
661
|
)))
|
|
669
662
|
}
|
|
670
663
|
}
|
|
@@ -769,8 +762,7 @@ fn convert_payloads(
|
|
|
769
762
|
) -> Result<Option<Payload>, WFMachinesError> {
|
|
770
763
|
result.map(TryInto::try_into).transpose().map_err(|pe| {
|
|
771
764
|
WFMachinesError::Fatal(format!(
|
|
772
|
-
"Not exactly one payload in activity result ({}) for event: {:?}"
|
|
773
|
-
pe, event_info
|
|
765
|
+
"Not exactly one payload in activity result ({pe}) for event: {event_info:?}"
|
|
774
766
|
))
|
|
775
767
|
})
|
|
776
768
|
}
|
|
@@ -161,15 +161,13 @@ impl TryFrom<HistoryEvent> for CancelExternalMachineEvents {
|
|
|
161
161
|
Self::RequestCancelExternalWorkflowExecutionFailed(attrs.cause())
|
|
162
162
|
} else {
|
|
163
163
|
return Err(WFMachinesError::Fatal(format!(
|
|
164
|
-
"Cancelworkflow failed attributes were unset: {}"
|
|
165
|
-
e
|
|
164
|
+
"Cancelworkflow failed attributes were unset: {e}"
|
|
166
165
|
)));
|
|
167
166
|
}
|
|
168
167
|
}
|
|
169
168
|
_ => {
|
|
170
169
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
171
|
-
"Cancel external WF machine does not handle this event: {}"
|
|
172
|
-
e
|
|
170
|
+
"Cancel external WF machine does not handle this event: {e}"
|
|
173
171
|
)))
|
|
174
172
|
}
|
|
175
173
|
})
|
|
@@ -199,7 +197,7 @@ impl WFMachinesAdapter for CancelExternalMachine {
|
|
|
199
197
|
vec![ResolveRequestCancelExternalWorkflow {
|
|
200
198
|
seq: self.shared_state.seq,
|
|
201
199
|
failure: Some(Failure {
|
|
202
|
-
message: format!("Unable to cancel external workflow because {}"
|
|
200
|
+
message: format!("Unable to cancel external workflow because {reason}"),
|
|
203
201
|
failure_info: Some(FailureInfo::ApplicationFailureInfo(
|
|
204
202
|
ApplicationFailureInfo {
|
|
205
203
|
r#type: f.to_string(),
|
|
@@ -80,8 +80,7 @@ impl TryFrom<HistoryEvent> for CancelWorkflowMachineEvents {
|
|
|
80
80
|
Some(EventType::WorkflowExecutionCanceled) => Self::WorkflowExecutionCanceled,
|
|
81
81
|
_ => {
|
|
82
82
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
83
|
-
"Cancel workflow machine does not handle this event: {}"
|
|
84
|
-
e
|
|
83
|
+
"Cancel workflow machine does not handle this event: {e}"
|
|
85
84
|
)))
|
|
86
85
|
}
|
|
87
86
|
})
|
|
@@ -471,8 +471,7 @@ impl TryFrom<HistoryEvent> for ChildWorkflowMachineEvents {
|
|
|
471
471
|
}
|
|
472
472
|
_ => {
|
|
473
473
|
return Err(WFMachinesError::Fatal(format!(
|
|
474
|
-
"Child workflow machine does not handle this event: {:?}"
|
|
475
|
-
e
|
|
474
|
+
"Child workflow machine does not handle this event: {e:?}"
|
|
476
475
|
)))
|
|
477
476
|
}
|
|
478
477
|
})
|
|
@@ -612,7 +611,7 @@ impl Cancellable for ChildWorkflowMachine {
|
|
|
612
611
|
| c @ ChildWorkflowCommand::IssueCancelAfterStarted { .. } => {
|
|
613
612
|
self.adapt_response(c, None)
|
|
614
613
|
}
|
|
615
|
-
x => panic!("Invalid cancel event response {:?}"
|
|
614
|
+
x => panic!("Invalid cancel event response {x:?}"),
|
|
616
615
|
})
|
|
617
616
|
.collect::<Result<Vec<_>, _>>()?
|
|
618
617
|
.into_iter()
|
|
@@ -650,8 +649,7 @@ fn convert_payloads(
|
|
|
650
649
|
) -> Result<Option<Payload>, WFMachinesError> {
|
|
651
650
|
result.map(TryInto::try_into).transpose().map_err(|pe| {
|
|
652
651
|
WFMachinesError::Fatal(format!(
|
|
653
|
-
"Not exactly one payload in child workflow result ({}) for event: {:?}"
|
|
654
|
-
pe, event_info
|
|
652
|
+
"Not exactly one payload in child workflow result ({pe}) for event: {event_info:?}"
|
|
655
653
|
))
|
|
656
654
|
})
|
|
657
655
|
}
|
|
@@ -69,8 +69,7 @@ impl TryFrom<HistoryEvent> for CompleteWorkflowMachineEvents {
|
|
|
69
69
|
EventType::WorkflowExecutionCompleted => Self::WorkflowExecutionCompleted,
|
|
70
70
|
_ => {
|
|
71
71
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
72
|
-
"Complete workflow machine does not handle this event: {}"
|
|
73
|
-
e
|
|
72
|
+
"Complete workflow machine does not handle this event: {e}"
|
|
74
73
|
)))
|
|
75
74
|
}
|
|
76
75
|
})
|
package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs
CHANGED
|
@@ -77,8 +77,7 @@ impl TryFrom<HistoryEvent> for ContinueAsNewWorkflowMachineEvents {
|
|
|
77
77
|
EventType::WorkflowExecutionContinuedAsNew => Self::WorkflowExecutionContinuedAsNew,
|
|
78
78
|
_ => {
|
|
79
79
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
80
|
-
"Continue as new workflow machine does not handle this event: {}"
|
|
81
|
-
e
|
|
80
|
+
"Continue as new workflow machine does not handle this event: {e}"
|
|
82
81
|
)))
|
|
83
82
|
}
|
|
84
83
|
})
|
|
@@ -93,8 +93,7 @@ impl TryFrom<HistoryEvent> for FailWorkflowMachineEvents {
|
|
|
93
93
|
EventType::WorkflowExecutionFailed => Self::WorkflowExecutionFailed,
|
|
94
94
|
_ => {
|
|
95
95
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
96
|
-
"Fail workflow machine does not handle this event: {}"
|
|
97
|
-
e
|
|
96
|
+
"Fail workflow machine does not handle this event: {e}"
|
|
98
97
|
)))
|
|
99
98
|
}
|
|
100
99
|
})
|
|
@@ -59,15 +59,17 @@ fsm! {
|
|
|
59
59
|
--> MarkerCommandRecorded;
|
|
60
60
|
|
|
61
61
|
// Replay path ================================================================================
|
|
62
|
-
// LAs on the replay path
|
|
63
|
-
// to eventually see the marker
|
|
62
|
+
// LAs on the replay path always need to eventually see the marker
|
|
64
63
|
WaitingMarkerEvent --(MarkerRecorded(CompleteLocalActivityData), shared on_marker_recorded)
|
|
65
64
|
--> MarkerCommandRecorded;
|
|
66
65
|
// If we are told to cancel while waiting for the marker, we still need to wait for the marker.
|
|
67
|
-
WaitingMarkerEvent --(Cancel, on_cancel_requested) -->
|
|
66
|
+
WaitingMarkerEvent --(Cancel, on_cancel_requested) --> WaitingMarkerEvent;
|
|
67
|
+
// Because there could be non-heartbeat WFTs (ex: signals being received) between scheduling
|
|
68
|
+
// the LA and the marker being recorded, peekahead might not always resolve the LA *before*
|
|
69
|
+
// scheduling it. This transition accounts for that.
|
|
70
|
+
WaitingMarkerEvent --(HandleKnownResult(ResolveDat), on_handle_result) --> WaitingMarkerEvent;
|
|
68
71
|
WaitingMarkerEvent --(NoWaitCancel(ActivityCancellationType),
|
|
69
|
-
on_no_wait_cancel) -->
|
|
70
|
-
WaitingMarkerEventCancelled --(HandleResult(ResolveDat), on_handle_result) --> WaitingMarkerEvent;
|
|
72
|
+
on_no_wait_cancel) --> WaitingMarkerEvent;
|
|
71
73
|
|
|
72
74
|
// It is entirely possible to have started the LA while replaying, only to find that we have
|
|
73
75
|
// reached a new WFT and there still was no marker. In such cases we need to execute the LA.
|
|
@@ -135,7 +137,7 @@ impl From<CompleteLocalActivityData> for ResolveDat {
|
|
|
135
137
|
/// must resolve before we send a record marker command. A [MachineResponse] may be produced,
|
|
136
138
|
/// to queue the LA for execution if it needs to be.
|
|
137
139
|
pub(super) fn new_local_activity(
|
|
138
|
-
attrs: ValidScheduleLA,
|
|
140
|
+
mut attrs: ValidScheduleLA,
|
|
139
141
|
replaying_when_invoked: bool,
|
|
140
142
|
maybe_pre_resolved: Option<ResolveDat>,
|
|
141
143
|
wf_time: Option<SystemTime>,
|
|
@@ -155,6 +157,11 @@ pub(super) fn new_local_activity(
|
|
|
155
157
|
Executing {}.into()
|
|
156
158
|
};
|
|
157
159
|
|
|
160
|
+
// If the scheduled LA doesn't already have an "original" schedule time, assign one.
|
|
161
|
+
attrs
|
|
162
|
+
.original_schedule_time
|
|
163
|
+
.get_or_insert(SystemTime::now());
|
|
164
|
+
|
|
158
165
|
let mut machine = LocalActivityMachine {
|
|
159
166
|
state: initial_state,
|
|
160
167
|
shared_state: SharedState {
|
|
@@ -197,6 +204,12 @@ impl LocalActivityMachine {
|
|
|
197
204
|
}
|
|
198
205
|
}
|
|
199
206
|
|
|
207
|
+
/// Returns true if the machine will willingly accept data from a marker in its current state.
|
|
208
|
+
/// IE: Calling [Self::try_resolve_with_dat] makes sense.
|
|
209
|
+
pub(super) fn will_accept_resolve_marker(&self) -> bool {
|
|
210
|
+
matches!(self.state, LocalActivityMachineState::WaitingMarkerEvent(_))
|
|
211
|
+
}
|
|
212
|
+
|
|
200
213
|
/// Must be called if the workflow encounters a non-replay workflow task
|
|
201
214
|
pub(super) fn encountered_non_replay_wft(
|
|
202
215
|
&mut self,
|
|
@@ -235,28 +248,45 @@ impl LocalActivityMachine {
|
|
|
235
248
|
backoff: Option<prost_types::Duration>,
|
|
236
249
|
original_schedule_time: Option<SystemTime>,
|
|
237
250
|
) -> Result<Vec<MachineResponse>, WFMachinesError> {
|
|
238
|
-
self.
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
251
|
+
self._try_resolve(
|
|
252
|
+
ResolveDat {
|
|
253
|
+
result,
|
|
254
|
+
complete_time: self.shared_state.wf_time_when_started.map(|t| t + runtime),
|
|
255
|
+
attempt,
|
|
256
|
+
backoff,
|
|
257
|
+
original_schedule_time,
|
|
258
|
+
},
|
|
259
|
+
false,
|
|
260
|
+
)
|
|
245
261
|
}
|
|
262
|
+
|
|
246
263
|
/// Attempt to resolve the local activity with already known data, ex pre-resolved data
|
|
247
264
|
pub(super) fn try_resolve_with_dat(
|
|
248
265
|
&mut self,
|
|
249
266
|
dat: ResolveDat,
|
|
250
267
|
) -> Result<Vec<MachineResponse>, WFMachinesError> {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
268
|
+
self._try_resolve(dat, true)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
fn _try_resolve(
|
|
272
|
+
&mut self,
|
|
273
|
+
dat: ResolveDat,
|
|
274
|
+
from_marker: bool,
|
|
275
|
+
) -> Result<Vec<MachineResponse>, WFMachinesError> {
|
|
276
|
+
let evt = if from_marker {
|
|
277
|
+
LocalActivityMachineEvents::HandleKnownResult(dat)
|
|
278
|
+
} else {
|
|
279
|
+
LocalActivityMachineEvents::HandleResult(dat)
|
|
280
|
+
};
|
|
281
|
+
let res = OnEventWrapper::on_event_mut(self, evt).map_err(|e| match e {
|
|
282
|
+
MachineError::InvalidTransition => WFMachinesError::Fatal(format!(
|
|
283
|
+
"Invalid transition resolving local activity (seq {}, from marker: {}) in {}",
|
|
284
|
+
self.shared_state.attrs.seq,
|
|
285
|
+
from_marker,
|
|
286
|
+
self.state(),
|
|
287
|
+
)),
|
|
288
|
+
MachineError::Underlying(e) => e,
|
|
289
|
+
})?;
|
|
260
290
|
|
|
261
291
|
Ok(res
|
|
262
292
|
.into_iter()
|
|
@@ -505,6 +535,17 @@ impl WaitingMarkerEvent {
|
|
|
505
535
|
})
|
|
506
536
|
)
|
|
507
537
|
}
|
|
538
|
+
fn on_handle_result(
|
|
539
|
+
self,
|
|
540
|
+
dat: ResolveDat,
|
|
541
|
+
) -> LocalActivityMachineTransition<WaitingMarkerEvent> {
|
|
542
|
+
TransitionResult::ok(
|
|
543
|
+
[LocalActivityCommand::Resolved(dat)],
|
|
544
|
+
WaitingMarkerEvent {
|
|
545
|
+
already_resolved: true,
|
|
546
|
+
},
|
|
547
|
+
)
|
|
548
|
+
}
|
|
508
549
|
pub(super) fn on_started_non_replay_wft(
|
|
509
550
|
self,
|
|
510
551
|
mut dat: SharedState,
|
|
@@ -520,41 +561,22 @@ impl WaitingMarkerEvent {
|
|
|
520
561
|
)
|
|
521
562
|
}
|
|
522
563
|
|
|
523
|
-
fn on_cancel_requested(self) -> LocalActivityMachineTransition<
|
|
564
|
+
fn on_cancel_requested(self) -> LocalActivityMachineTransition<WaitingMarkerEvent> {
|
|
524
565
|
// We still "request a cancel" even though we know the local activity should not be running
|
|
525
566
|
// because the data might be in the pre-resolved list.
|
|
526
|
-
TransitionResult::ok(
|
|
527
|
-
[LocalActivityCommand::RequestCancel],
|
|
528
|
-
WaitingMarkerEventCancelled {},
|
|
529
|
-
)
|
|
567
|
+
TransitionResult::ok([LocalActivityCommand::RequestCancel], self)
|
|
530
568
|
}
|
|
531
569
|
|
|
532
570
|
fn on_no_wait_cancel(
|
|
533
571
|
self,
|
|
534
572
|
_: ActivityCancellationType,
|
|
535
|
-
) -> LocalActivityMachineTransition<
|
|
573
|
+
) -> LocalActivityMachineTransition<WaitingMarkerEvent> {
|
|
536
574
|
// Markers are always recorded when cancelling, so this is the same as a normal cancel on
|
|
537
575
|
// the replay path
|
|
538
576
|
self.on_cancel_requested()
|
|
539
577
|
}
|
|
540
578
|
}
|
|
541
579
|
|
|
542
|
-
#[derive(Default, Clone)]
|
|
543
|
-
pub(super) struct WaitingMarkerEventCancelled {}
|
|
544
|
-
impl WaitingMarkerEventCancelled {
|
|
545
|
-
fn on_handle_result(
|
|
546
|
-
self,
|
|
547
|
-
dat: ResolveDat,
|
|
548
|
-
) -> LocalActivityMachineTransition<WaitingMarkerEvent> {
|
|
549
|
-
TransitionResult::ok(
|
|
550
|
-
[LocalActivityCommand::Resolved(dat)],
|
|
551
|
-
WaitingMarkerEvent {
|
|
552
|
-
already_resolved: true,
|
|
553
|
-
},
|
|
554
|
-
)
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
|
|
558
580
|
#[derive(Default, Clone)]
|
|
559
581
|
pub(super) struct WaitingMarkerEventPreResolved {}
|
|
560
582
|
impl WaitingMarkerEventPreResolved {
|
|
@@ -733,8 +755,7 @@ impl TryFrom<HistoryEvent> for LocalActivityMachineEvents {
|
|
|
733
755
|
fn try_from(e: HistoryEvent) -> Result<Self, Self::Error> {
|
|
734
756
|
if e.event_type() != EventType::MarkerRecorded {
|
|
735
757
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
736
|
-
"Local activity machine cannot handle this event: {}"
|
|
737
|
-
e
|
|
758
|
+
"Local activity machine cannot handle this event: {e}"
|
|
738
759
|
)));
|
|
739
760
|
}
|
|
740
761
|
|
|
@@ -1403,8 +1424,9 @@ mod tests {
|
|
|
1403
1424
|
assert_eq!(commands[1].command_type, CommandType::StartTimer as i32);
|
|
1404
1425
|
}
|
|
1405
1426
|
|
|
1406
|
-
if replay {
|
|
1407
|
-
wfm.get_next_activation().await.unwrap()
|
|
1427
|
+
let commands = if replay {
|
|
1428
|
+
wfm.get_next_activation().await.unwrap();
|
|
1429
|
+
wfm.get_server_commands().commands
|
|
1408
1430
|
} else {
|
|
1409
1431
|
// On non replay, there's an additional activation, because completing with the cancel
|
|
1410
1432
|
// wants to wake up the workflow to see if resolving the LA as cancelled did anything.
|
|
@@ -1429,11 +1451,11 @@ mod tests {
|
|
|
1429
1451
|
|
|
1430
1452
|
wfm.new_history(t.get_history_info(3).unwrap().into())
|
|
1431
1453
|
.await
|
|
1432
|
-
.unwrap()
|
|
1454
|
+
.unwrap();
|
|
1455
|
+
wfm.get_next_activation().await.unwrap();
|
|
1456
|
+
wfm.get_server_commands().commands
|
|
1433
1457
|
};
|
|
1434
1458
|
|
|
1435
|
-
wfm.get_next_activation().await.unwrap();
|
|
1436
|
-
let commands = wfm.get_server_commands().commands;
|
|
1437
1459
|
assert_eq!(commands.len(), 1);
|
|
1438
1460
|
assert_eq!(
|
|
1439
1461
|
commands[0].command_type,
|
|
@@ -18,9 +18,9 @@ mod workflow_task_state_machine;
|
|
|
18
18
|
#[cfg(test)]
|
|
19
19
|
mod transition_coverage;
|
|
20
20
|
|
|
21
|
-
pub(crate) use workflow_machines::
|
|
21
|
+
pub(crate) use workflow_machines::WorkflowMachines;
|
|
22
22
|
|
|
23
|
-
use crate::telemetry::VecDisplayer;
|
|
23
|
+
use crate::{telemetry::VecDisplayer, worker::workflow::WFMachinesError};
|
|
24
24
|
use activity_state_machine::ActivityMachine;
|
|
25
25
|
use cancel_external_state_machine::CancelExternalMachine;
|
|
26
26
|
use cancel_workflow_state_machine::CancelWorkflowMachine;
|
|
@@ -217,7 +217,7 @@ where
|
|
|
217
217
|
<SM as StateMachine>::State: Display,
|
|
218
218
|
{
|
|
219
219
|
if !commands.is_empty() {
|
|
220
|
-
|
|
220
|
+
trace!(commands=%commands.display(), state=%machine.state(),
|
|
221
221
|
machine_name=%TemporalStateMachine::name(machine), "Machine produced commands");
|
|
222
222
|
}
|
|
223
223
|
let mut machine_responses = vec![];
|
package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
use super::{
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
use super::{workflow_machines::MachineResponse, NewMachineWithCommand};
|
|
2
|
+
use crate::worker::workflow::{
|
|
3
|
+
machines::{Cancellable, EventInfo, WFMachinesAdapter},
|
|
4
|
+
WFMachinesError,
|
|
4
5
|
};
|
|
5
|
-
use crate::worker::workflow::machines::{Cancellable, EventInfo, WFMachinesAdapter};
|
|
6
6
|
use rustfsm::{fsm, TransitionResult};
|
|
7
7
|
use temporal_sdk_core_protos::{
|
|
8
8
|
coresdk::workflow_commands::ModifyWorkflowProperties,
|
|
@@ -208,8 +208,7 @@ impl TryFrom<HistoryEvent> for PatchMachineEvents {
|
|
|
208
208
|
match e.get_patch_marker_details() {
|
|
209
209
|
Some((id, _)) => Ok(Self::MarkerRecorded(id)),
|
|
210
210
|
_ => Err(WFMachinesError::Nondeterminism(format!(
|
|
211
|
-
"Change machine cannot handle this event: {}"
|
|
212
|
-
e
|
|
211
|
+
"Change machine cannot handle this event: {e}"
|
|
213
212
|
))),
|
|
214
213
|
}
|
|
215
214
|
}
|
|
@@ -202,15 +202,13 @@ impl TryFrom<HistoryEvent> for SignalExternalMachineEvents {
|
|
|
202
202
|
Self::SignalExternalWorkflowExecutionFailed(attrs.cause())
|
|
203
203
|
} else {
|
|
204
204
|
return Err(WFMachinesError::Fatal(format!(
|
|
205
|
-
"Signal workflow failed attributes were unset: {}"
|
|
206
|
-
e
|
|
205
|
+
"Signal workflow failed attributes were unset: {e}"
|
|
207
206
|
)));
|
|
208
207
|
}
|
|
209
208
|
}
|
|
210
209
|
_ => {
|
|
211
210
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
212
|
-
"Signal external WF machine does not handle this event: {}"
|
|
213
|
-
e
|
|
211
|
+
"Signal external WF machine does not handle this event: {e}"
|
|
214
212
|
)))
|
|
215
213
|
}
|
|
216
214
|
})
|
|
@@ -242,7 +240,7 @@ impl WFMachinesAdapter for SignalExternalMachine {
|
|
|
242
240
|
seq: self.shared_state.seq,
|
|
243
241
|
// TODO: Create new failure type upstream for this
|
|
244
242
|
failure: Some(Failure {
|
|
245
|
-
message: format!("Unable to signal external workflow because {}"
|
|
243
|
+
message: format!("Unable to signal external workflow because {reason}"),
|
|
246
244
|
failure_info: Some(FailureInfo::ApplicationFailureInfo(
|
|
247
245
|
ApplicationFailureInfo {
|
|
248
246
|
r#type: f.to_string(),
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#![allow(clippy::large_enum_variant)]
|
|
2
2
|
|
|
3
3
|
use super::{
|
|
4
|
-
workflow_machines::
|
|
5
|
-
|
|
4
|
+
workflow_machines::MachineResponse, Cancellable, EventInfo, NewMachineWithCommand,
|
|
5
|
+
OnEventWrapper, WFMachinesAdapter,
|
|
6
6
|
};
|
|
7
|
+
use crate::worker::workflow::WFMachinesError;
|
|
7
8
|
use rustfsm::{fsm, MachineError, StateMachine, TransitionResult};
|
|
8
9
|
use std::convert::TryFrom;
|
|
9
10
|
use temporal_sdk_core_protos::{
|
|
@@ -107,15 +108,13 @@ impl TryFrom<HistoryEvent> for TimerMachineEvents {
|
|
|
107
108
|
Self::TimerFired(attrs)
|
|
108
109
|
} else {
|
|
109
110
|
return Err(WFMachinesError::Fatal(format!(
|
|
110
|
-
"Timer fired attribs were unset: {}"
|
|
111
|
-
e
|
|
111
|
+
"Timer fired attribs were unset: {e}"
|
|
112
112
|
)));
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
_ => {
|
|
116
116
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
117
|
-
"Timer machine does not handle this event: {}"
|
|
118
|
-
e
|
|
117
|
+
"Timer machine does not handle this event: {e}"
|
|
119
118
|
)))
|
|
120
119
|
}
|
|
121
120
|
})
|
|
@@ -256,7 +255,7 @@ impl Cancellable for TimerMachine {
|
|
|
256
255
|
vec![MachineResponse::IssueNewCommand(cmd)]
|
|
257
256
|
}
|
|
258
257
|
None => vec![],
|
|
259
|
-
x => panic!("Invalid cancel event response {:?}"
|
|
258
|
+
x => panic!("Invalid cancel event response {x:?}"),
|
|
260
259
|
},
|
|
261
260
|
)
|
|
262
261
|
}
|
|
@@ -144,7 +144,7 @@ mod machine_coverage_report {
|
|
|
144
144
|
m @ "ModifyWorkflowPropertiesMachine" => {
|
|
145
145
|
cover_transitions(m, &mut modify_wf_props, coverage)
|
|
146
146
|
}
|
|
147
|
-
m => panic!("Unknown machine {}"
|
|
147
|
+
m => panic!("Unknown machine {m}"),
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
}
|
|
@@ -168,7 +168,7 @@ mod machine_coverage_report {
|
|
|
168
168
|
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
|
169
169
|
d.push("machine_coverage");
|
|
170
170
|
std::fs::create_dir_all(&d).unwrap();
|
|
171
|
-
d.push(format!("{}_Coverage.puml"
|
|
171
|
+
d.push(format!("{machine}_Coverage.puml"));
|
|
172
172
|
let mut file = File::create(d).unwrap();
|
|
173
173
|
file.write_all(viz.as_bytes()).unwrap();
|
|
174
174
|
}
|
package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
use super::{
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
use super::{workflow_machines::MachineResponse, NewMachineWithCommand};
|
|
2
|
+
use crate::worker::workflow::{
|
|
3
|
+
machines::{Cancellable, EventInfo, WFMachinesAdapter},
|
|
4
|
+
WFMachinesError,
|
|
4
5
|
};
|
|
5
|
-
use crate::worker::workflow::machines::{Cancellable, EventInfo, WFMachinesAdapter};
|
|
6
6
|
use rustfsm::{fsm, TransitionResult};
|
|
7
7
|
use temporal_sdk_core_protos::{
|
|
8
8
|
coresdk::workflow_commands::UpsertWorkflowSearchAttributes,
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
use super::super::
|
|
1
|
+
use super::super::local_activity_state_machine::ResolveDat;
|
|
2
2
|
use crate::{
|
|
3
|
-
protosext::{
|
|
3
|
+
protosext::{CompleteLocalActivityData, ValidScheduleLA},
|
|
4
4
|
worker::{ExecutingLAId, LocalActRequest, NewLocalAct},
|
|
5
5
|
};
|
|
6
6
|
use std::{
|
|
7
7
|
collections::{HashMap, HashSet},
|
|
8
8
|
time::SystemTime,
|
|
9
9
|
};
|
|
10
|
-
use temporal_sdk_core_protos::temporal::api::
|
|
11
|
-
common::v1::WorkflowExecution, history::v1::HistoryEvent,
|
|
12
|
-
};
|
|
10
|
+
use temporal_sdk_core_protos::temporal::api::common::v1::WorkflowExecution;
|
|
13
11
|
|
|
14
12
|
#[derive(Default)]
|
|
15
13
|
pub(super) struct LocalActivityData {
|
|
@@ -53,7 +51,7 @@ impl LocalActivityData {
|
|
|
53
51
|
.chain(self.new_requests.drain(..).map(|sa| {
|
|
54
52
|
self.executing.insert(sa.seq);
|
|
55
53
|
LocalActRequest::New(NewLocalAct {
|
|
56
|
-
schedule_time:
|
|
54
|
+
schedule_time: SystemTime::now(),
|
|
57
55
|
schedule_cmd: sa,
|
|
58
56
|
workflow_type: wf_type.to_string(),
|
|
59
57
|
workflow_exec_info: WorkflowExecution {
|
|
@@ -70,17 +68,8 @@ impl LocalActivityData {
|
|
|
70
68
|
self.executing.len() + self.new_requests.len()
|
|
71
69
|
}
|
|
72
70
|
|
|
73
|
-
pub(super) fn
|
|
74
|
-
|
|
75
|
-
self.preresolutions
|
|
76
|
-
.insert(la_dat.marker_dat.seq, la_dat.into());
|
|
77
|
-
} else {
|
|
78
|
-
return Err(WFMachinesError::Fatal(format!(
|
|
79
|
-
"Local activity marker was unparsable: {:?}",
|
|
80
|
-
e
|
|
81
|
-
)));
|
|
82
|
-
}
|
|
83
|
-
Ok(())
|
|
71
|
+
pub(super) fn insert_peeked_marker(&mut self, dat: CompleteLocalActivityData) {
|
|
72
|
+
self.preresolutions.insert(dat.marker_dat.seq, dat.into());
|
|
84
73
|
}
|
|
85
74
|
|
|
86
75
|
pub(super) fn take_preresolution(&mut self, seq: u32) -> Option<ResolveDat> {
|