temporalio 0.0.2 → 0.1.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.
- checksums.yaml +4 -4
- data/README.md +25 -23
- data/bridge/Cargo.lock +168 -59
- data/bridge/Cargo.toml +4 -2
- data/bridge/sdk-core/README.md +19 -6
- data/bridge/sdk-core/client/src/lib.rs +215 -39
- data/bridge/sdk-core/client/src/metrics.rs +17 -8
- data/bridge/sdk-core/client/src/raw.rs +4 -4
- data/bridge/sdk-core/client/src/retry.rs +32 -20
- data/bridge/sdk-core/core/Cargo.toml +22 -9
- data/bridge/sdk-core/core/src/abstractions.rs +203 -14
- data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +76 -41
- data/bridge/sdk-core/core/src/core_tests/determinism.rs +165 -2
- data/bridge/sdk-core/core/src/core_tests/local_activities.rs +204 -83
- data/bridge/sdk-core/core/src/core_tests/queries.rs +3 -4
- data/bridge/sdk-core/core/src/core_tests/workers.rs +1 -3
- data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +397 -54
- data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +106 -12
- data/bridge/sdk-core/core/src/internal_flags.rs +136 -0
- data/bridge/sdk-core/core/src/lib.rs +16 -9
- data/bridge/sdk-core/core/src/telemetry/log_export.rs +1 -1
- data/bridge/sdk-core/core/src/telemetry/metrics.rs +69 -35
- data/bridge/sdk-core/core/src/telemetry/mod.rs +29 -13
- data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +17 -12
- data/bridge/sdk-core/core/src/test_help/mod.rs +62 -12
- data/bridge/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +112 -156
- data/bridge/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +89 -0
- data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +352 -122
- data/bridge/sdk-core/core/src/worker/activities.rs +233 -157
- data/bridge/sdk-core/core/src/worker/client/mocks.rs +22 -2
- data/bridge/sdk-core/core/src/worker/client.rs +18 -2
- data/bridge/sdk-core/core/src/worker/mod.rs +165 -58
- data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +1 -3
- data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -5
- data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +856 -277
- data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +100 -43
- data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +7 -7
- data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +5 -4
- data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +87 -27
- data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +5 -4
- data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +5 -4
- data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +5 -4
- data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +137 -62
- data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +25 -17
- data/bridge/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +7 -6
- data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +103 -152
- data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +7 -7
- data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +9 -9
- data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +2 -2
- data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +14 -7
- data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +5 -16
- data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +201 -121
- data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +11 -14
- data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +30 -15
- data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +1026 -376
- data/bridge/sdk-core/core/src/worker/workflow/mod.rs +460 -384
- data/bridge/sdk-core/core/src/worker/workflow/run_cache.rs +40 -57
- data/bridge/sdk-core/core/src/worker/workflow/wft_extraction.rs +125 -0
- data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +1 -4
- data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +117 -0
- data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +24 -0
- data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +448 -718
- data/bridge/sdk-core/core-api/Cargo.toml +2 -1
- data/bridge/sdk-core/core-api/src/errors.rs +1 -34
- data/bridge/sdk-core/core-api/src/lib.rs +6 -2
- data/bridge/sdk-core/core-api/src/telemetry.rs +0 -6
- data/bridge/sdk-core/core-api/src/worker.rs +14 -1
- data/bridge/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +18 -15
- data/bridge/sdk-core/fsm/rustfsm_trait/src/lib.rs +8 -3
- data/bridge/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +5 -17
- data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +11 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +1 -6
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +6 -6
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +5 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +22 -6
- data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +48 -19
- data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +2 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +3 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/{enums/v1/interaction_type.proto → protocol/v1/message.proto} +29 -11
- data/bridge/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +63 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +111 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +59 -28
- data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +2 -2
- data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +1 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +1 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +1 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/common/common.proto +1 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +1 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +1 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +7 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +1 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +6 -0
- data/bridge/sdk-core/sdk/Cargo.toml +3 -2
- data/bridge/sdk-core/sdk/src/lib.rs +87 -20
- data/bridge/sdk-core/sdk/src/workflow_future.rs +9 -8
- data/bridge/sdk-core/sdk-core-protos/Cargo.toml +5 -2
- data/bridge/sdk-core/sdk-core-protos/build.rs +36 -1
- data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +100 -87
- data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +5 -1
- data/bridge/sdk-core/sdk-core-protos/src/lib.rs +175 -57
- data/bridge/sdk-core/sdk-core-protos/src/task_token.rs +12 -2
- data/bridge/sdk-core/test-utils/Cargo.toml +3 -1
- data/bridge/sdk-core/test-utils/src/canned_histories.rs +106 -296
- data/bridge/sdk-core/test-utils/src/histfetch.rs +1 -1
- data/bridge/sdk-core/test-utils/src/lib.rs +82 -23
- data/bridge/sdk-core/test-utils/src/wf_input_saver.rs +50 -0
- data/bridge/sdk-core/test-utils/src/workflows.rs +29 -0
- data/bridge/sdk-core/tests/fuzzy_workflow.rs +130 -0
- data/bridge/sdk-core/tests/{load_tests.rs → heavy_tests.rs} +125 -51
- data/bridge/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +25 -3
- data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +5 -3
- data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +218 -16
- data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +4 -47
- data/bridge/sdk-core/tests/integ_tests/queries_tests.rs +5 -128
- data/bridge/sdk-core/tests/integ_tests/visibility_tests.rs +83 -25
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/activities.rs +93 -69
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +6 -13
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +1 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +6 -2
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -10
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +72 -191
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +1 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/patches.rs +7 -28
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +12 -7
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/signals.rs +18 -14
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +6 -20
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/timers.rs +10 -21
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +6 -4
- data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +10 -11
- data/bridge/sdk-core/tests/main.rs +3 -13
- data/bridge/sdk-core/tests/runner.rs +75 -36
- data/bridge/sdk-core/tests/wf_input_replay.rs +32 -0
- data/bridge/src/connection.rs +41 -25
- data/bridge/src/lib.rs +269 -14
- data/bridge/src/runtime.rs +1 -1
- data/bridge/src/test_server.rs +153 -0
- data/bridge/src/worker.rs +89 -16
- data/lib/gen/temporal/api/command/v1/message_pb.rb +4 -18
- data/lib/gen/temporal/api/common/v1/message_pb.rb +4 -0
- data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +1 -3
- data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +3 -3
- data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +2 -0
- data/lib/gen/temporal/api/enums/v1/update_pb.rb +6 -4
- data/lib/gen/temporal/api/history/v1/message_pb.rb +27 -19
- data/lib/gen/temporal/api/namespace/v1/message_pb.rb +1 -0
- data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +3 -0
- data/lib/gen/temporal/api/protocol/v1/message_pb.rb +30 -0
- data/lib/gen/temporal/api/sdk/v1/task_complete_metadata_pb.rb +23 -0
- data/lib/gen/temporal/api/testservice/v1/request_response_pb.rb +49 -0
- data/lib/gen/temporal/api/testservice/v1/service_pb.rb +21 -0
- data/lib/gen/temporal/api/update/v1/message_pb.rb +72 -0
- data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +26 -16
- data/lib/gen/temporal/sdk/core/activity_result/activity_result_pb.rb +13 -9
- data/lib/gen/temporal/sdk/core/activity_task/activity_task_pb.rb +10 -6
- data/lib/gen/temporal/sdk/core/child_workflow/child_workflow_pb.rb +13 -9
- data/lib/gen/temporal/sdk/core/common/common_pb.rb +7 -3
- data/lib/gen/temporal/sdk/core/core_interface_pb.rb +9 -3
- data/lib/gen/temporal/sdk/core/external_data/external_data_pb.rb +7 -3
- data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +27 -21
- data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +28 -24
- data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +12 -5
- data/lib/temporalio/activity/context.rb +13 -8
- data/lib/temporalio/activity/info.rb +1 -1
- data/lib/temporalio/bridge/connect_options.rb +15 -0
- data/lib/temporalio/bridge/retry_config.rb +24 -0
- data/lib/temporalio/bridge/tls_options.rb +19 -0
- data/lib/temporalio/client/implementation.rb +8 -8
- data/lib/temporalio/connection/retry_config.rb +44 -0
- data/lib/temporalio/connection/service.rb +20 -0
- data/lib/temporalio/connection/test_service.rb +92 -0
- data/lib/temporalio/connection/tls_options.rb +51 -0
- data/lib/temporalio/connection/workflow_service.rb +731 -0
- data/lib/temporalio/connection.rb +55 -720
- data/lib/temporalio/interceptor/activity_inbound.rb +22 -0
- data/lib/temporalio/interceptor/activity_outbound.rb +24 -0
- data/lib/temporalio/interceptor/chain.rb +5 -5
- data/lib/temporalio/interceptor/client.rb +8 -4
- data/lib/temporalio/interceptor.rb +22 -0
- data/lib/temporalio/retry_policy.rb +13 -3
- data/lib/temporalio/testing/time_skipping_handle.rb +32 -0
- data/lib/temporalio/testing/time_skipping_interceptor.rb +23 -0
- data/lib/temporalio/testing/workflow_environment.rb +112 -0
- data/lib/temporalio/testing.rb +175 -0
- data/lib/temporalio/version.rb +1 -1
- data/lib/temporalio/worker/activity_runner.rb +26 -4
- data/lib/temporalio/worker/activity_worker.rb +44 -18
- data/lib/temporalio/worker/sync_worker.rb +47 -11
- data/lib/temporalio/worker.rb +27 -21
- data/lib/temporalio/workflow/async.rb +46 -0
- data/lib/temporalio/workflow/future.rb +138 -0
- data/lib/temporalio/workflow/info.rb +76 -0
- data/temporalio.gemspec +4 -3
- metadata +67 -17
- data/bridge/sdk-core/Cargo.lock +0 -2606
- data/bridge/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +0 -87
- data/lib/bridge.so +0 -0
- data/lib/gen/temporal/api/enums/v1/interaction_type_pb.rb +0 -25
- data/lib/gen/temporal/api/interaction/v1/message_pb.rb +0 -49
- data/lib/gen/temporal/sdk/core/bridge/bridge_pb.rb +0 -222
|
@@ -2,6 +2,7 @@ use super::{
|
|
|
2
2
|
workflow_machines::MachineResponse, Cancellable, EventInfo, NewMachineWithCommand,
|
|
3
3
|
OnEventWrapper, WFMachinesAdapter, WFMachinesError,
|
|
4
4
|
};
|
|
5
|
+
use crate::worker::workflow::machines::HistEventData;
|
|
5
6
|
use rustfsm::{fsm, TransitionResult};
|
|
6
7
|
use std::convert::TryFrom;
|
|
7
8
|
use temporal_sdk_core_protos::{
|
|
@@ -85,16 +86,16 @@ impl From<FailWorkflowCommandCreated> for FailWorkflowCommandRecorded {
|
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
|
|
88
|
-
impl TryFrom<
|
|
89
|
+
impl TryFrom<HistEventData> for FailWorkflowMachineEvents {
|
|
89
90
|
type Error = WFMachinesError;
|
|
90
91
|
|
|
91
|
-
fn try_from(e:
|
|
92
|
+
fn try_from(e: HistEventData) -> Result<Self, Self::Error> {
|
|
93
|
+
let e = e.event;
|
|
92
94
|
Ok(match e.event_type() {
|
|
93
95
|
EventType::WorkflowExecutionFailed => Self::WorkflowExecutionFailed,
|
|
94
96
|
_ => {
|
|
95
97
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
96
|
-
"Fail workflow machine does not handle this event: {}"
|
|
97
|
-
e
|
|
98
|
+
"Fail workflow machine does not handle this event: {e}"
|
|
98
99
|
)))
|
|
99
100
|
}
|
|
100
101
|
})
|
|
@@ -3,8 +3,12 @@ use super::{
|
|
|
3
3
|
WFMachinesError,
|
|
4
4
|
};
|
|
5
5
|
use crate::{
|
|
6
|
+
internal_flags::CoreInternalFlags,
|
|
6
7
|
protosext::{CompleteLocalActivityData, HistoryEventExt, ValidScheduleLA},
|
|
7
|
-
worker::{
|
|
8
|
+
worker::{
|
|
9
|
+
workflow::{machines::HistEventData, InternalFlagsRef, OutgoingJob},
|
|
10
|
+
LocalActivityExecutionResult,
|
|
11
|
+
},
|
|
8
12
|
};
|
|
9
13
|
use rustfsm::{fsm, MachineError, StateMachine, TransitionResult};
|
|
10
14
|
use std::{
|
|
@@ -59,15 +63,17 @@ fsm! {
|
|
|
59
63
|
--> MarkerCommandRecorded;
|
|
60
64
|
|
|
61
65
|
// Replay path ================================================================================
|
|
62
|
-
// LAs on the replay path
|
|
63
|
-
// to eventually see the marker
|
|
66
|
+
// LAs on the replay path always need to eventually see the marker
|
|
64
67
|
WaitingMarkerEvent --(MarkerRecorded(CompleteLocalActivityData), shared on_marker_recorded)
|
|
65
68
|
--> MarkerCommandRecorded;
|
|
66
69
|
// 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) -->
|
|
70
|
+
WaitingMarkerEvent --(Cancel, on_cancel_requested) --> WaitingMarkerEvent;
|
|
71
|
+
// Because there could be non-heartbeat WFTs (ex: signals being received) between scheduling
|
|
72
|
+
// the LA and the marker being recorded, peekahead might not always resolve the LA *before*
|
|
73
|
+
// scheduling it. This transition accounts for that.
|
|
74
|
+
WaitingMarkerEvent --(HandleKnownResult(ResolveDat), on_handle_result) --> WaitingMarkerEvent;
|
|
68
75
|
WaitingMarkerEvent --(NoWaitCancel(ActivityCancellationType),
|
|
69
|
-
on_no_wait_cancel) -->
|
|
70
|
-
WaitingMarkerEventCancelled --(HandleResult(ResolveDat), on_handle_result) --> WaitingMarkerEvent;
|
|
76
|
+
on_no_wait_cancel) --> WaitingMarkerEvent;
|
|
71
77
|
|
|
72
78
|
// It is entirely possible to have started the LA while replaying, only to find that we have
|
|
73
79
|
// reached a new WFT and there still was no marker. In such cases we need to execute the LA.
|
|
@@ -139,6 +145,7 @@ pub(super) fn new_local_activity(
|
|
|
139
145
|
replaying_when_invoked: bool,
|
|
140
146
|
maybe_pre_resolved: Option<ResolveDat>,
|
|
141
147
|
wf_time: Option<SystemTime>,
|
|
148
|
+
internal_flags: InternalFlagsRef,
|
|
142
149
|
) -> Result<(LocalActivityMachine, Vec<MachineResponse>), WFMachinesError> {
|
|
143
150
|
let initial_state = if replaying_when_invoked {
|
|
144
151
|
if let Some(dat) = maybe_pre_resolved {
|
|
@@ -166,6 +173,7 @@ pub(super) fn new_local_activity(
|
|
|
166
173
|
attrs,
|
|
167
174
|
replaying_when_invoked,
|
|
168
175
|
wf_time_when_started: wf_time,
|
|
176
|
+
internal_flags,
|
|
169
177
|
},
|
|
170
178
|
};
|
|
171
179
|
|
|
@@ -202,6 +210,12 @@ impl LocalActivityMachine {
|
|
|
202
210
|
}
|
|
203
211
|
}
|
|
204
212
|
|
|
213
|
+
/// Returns true if the machine will willingly accept data from a marker in its current state.
|
|
214
|
+
/// IE: Calling [Self::try_resolve_with_dat] makes sense.
|
|
215
|
+
pub(super) fn will_accept_resolve_marker(&self) -> bool {
|
|
216
|
+
matches!(self.state, LocalActivityMachineState::WaitingMarkerEvent(_))
|
|
217
|
+
}
|
|
218
|
+
|
|
205
219
|
/// Must be called if the workflow encounters a non-replay workflow task
|
|
206
220
|
pub(super) fn encountered_non_replay_wft(
|
|
207
221
|
&mut self,
|
|
@@ -240,28 +254,45 @@ impl LocalActivityMachine {
|
|
|
240
254
|
backoff: Option<prost_types::Duration>,
|
|
241
255
|
original_schedule_time: Option<SystemTime>,
|
|
242
256
|
) -> Result<Vec<MachineResponse>, WFMachinesError> {
|
|
243
|
-
self.
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
257
|
+
self._try_resolve(
|
|
258
|
+
ResolveDat {
|
|
259
|
+
result,
|
|
260
|
+
complete_time: self.shared_state.wf_time_when_started.map(|t| t + runtime),
|
|
261
|
+
attempt,
|
|
262
|
+
backoff,
|
|
263
|
+
original_schedule_time,
|
|
264
|
+
},
|
|
265
|
+
false,
|
|
266
|
+
)
|
|
250
267
|
}
|
|
268
|
+
|
|
251
269
|
/// Attempt to resolve the local activity with already known data, ex pre-resolved data
|
|
252
270
|
pub(super) fn try_resolve_with_dat(
|
|
253
271
|
&mut self,
|
|
254
272
|
dat: ResolveDat,
|
|
255
273
|
) -> Result<Vec<MachineResponse>, WFMachinesError> {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
274
|
+
self._try_resolve(dat, true)
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
fn _try_resolve(
|
|
278
|
+
&mut self,
|
|
279
|
+
dat: ResolveDat,
|
|
280
|
+
from_marker: bool,
|
|
281
|
+
) -> Result<Vec<MachineResponse>, WFMachinesError> {
|
|
282
|
+
let evt = if from_marker {
|
|
283
|
+
LocalActivityMachineEvents::HandleKnownResult(dat)
|
|
284
|
+
} else {
|
|
285
|
+
LocalActivityMachineEvents::HandleResult(dat)
|
|
286
|
+
};
|
|
287
|
+
let res = OnEventWrapper::on_event_mut(self, evt).map_err(|e| match e {
|
|
288
|
+
MachineError::InvalidTransition => WFMachinesError::Fatal(format!(
|
|
289
|
+
"Invalid transition resolving local activity (seq {}, from marker: {}) in {}",
|
|
290
|
+
self.shared_state.attrs.seq,
|
|
291
|
+
from_marker,
|
|
292
|
+
self.state(),
|
|
293
|
+
)),
|
|
294
|
+
MachineError::Underlying(e) => e,
|
|
295
|
+
})?;
|
|
265
296
|
|
|
266
297
|
Ok(res
|
|
267
298
|
.into_iter()
|
|
@@ -278,6 +309,7 @@ pub(super) struct SharedState {
|
|
|
278
309
|
attrs: ValidScheduleLA,
|
|
279
310
|
replaying_when_invoked: bool,
|
|
280
311
|
wf_time_when_started: Option<SystemTime>,
|
|
312
|
+
internal_flags: InternalFlagsRef,
|
|
281
313
|
}
|
|
282
314
|
|
|
283
315
|
impl SharedState {
|
|
@@ -510,6 +542,17 @@ impl WaitingMarkerEvent {
|
|
|
510
542
|
})
|
|
511
543
|
)
|
|
512
544
|
}
|
|
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
|
+
}
|
|
513
556
|
pub(super) fn on_started_non_replay_wft(
|
|
514
557
|
self,
|
|
515
558
|
mut dat: SharedState,
|
|
@@ -525,41 +568,22 @@ impl WaitingMarkerEvent {
|
|
|
525
568
|
)
|
|
526
569
|
}
|
|
527
570
|
|
|
528
|
-
fn on_cancel_requested(self) -> LocalActivityMachineTransition<
|
|
571
|
+
fn on_cancel_requested(self) -> LocalActivityMachineTransition<WaitingMarkerEvent> {
|
|
529
572
|
// We still "request a cancel" even though we know the local activity should not be running
|
|
530
573
|
// because the data might be in the pre-resolved list.
|
|
531
|
-
TransitionResult::ok(
|
|
532
|
-
[LocalActivityCommand::RequestCancel],
|
|
533
|
-
WaitingMarkerEventCancelled {},
|
|
534
|
-
)
|
|
574
|
+
TransitionResult::ok([LocalActivityCommand::RequestCancel], self)
|
|
535
575
|
}
|
|
536
576
|
|
|
537
577
|
fn on_no_wait_cancel(
|
|
538
578
|
self,
|
|
539
579
|
_: ActivityCancellationType,
|
|
540
|
-
) -> LocalActivityMachineTransition<
|
|
580
|
+
) -> LocalActivityMachineTransition<WaitingMarkerEvent> {
|
|
541
581
|
// Markers are always recorded when cancelling, so this is the same as a normal cancel on
|
|
542
582
|
// the replay path
|
|
543
583
|
self.on_cancel_requested()
|
|
544
584
|
}
|
|
545
585
|
}
|
|
546
586
|
|
|
547
|
-
#[derive(Default, Clone)]
|
|
548
|
-
pub(super) struct WaitingMarkerEventCancelled {}
|
|
549
|
-
impl WaitingMarkerEventCancelled {
|
|
550
|
-
fn on_handle_result(
|
|
551
|
-
self,
|
|
552
|
-
dat: ResolveDat,
|
|
553
|
-
) -> LocalActivityMachineTransition<WaitingMarkerEvent> {
|
|
554
|
-
TransitionResult::ok(
|
|
555
|
-
[LocalActivityCommand::Resolved(dat)],
|
|
556
|
-
WaitingMarkerEvent {
|
|
557
|
-
already_resolved: true,
|
|
558
|
-
},
|
|
559
|
-
)
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
|
|
563
587
|
#[derive(Default, Clone)]
|
|
564
588
|
pub(super) struct WaitingMarkerEventPreResolved {}
|
|
565
589
|
impl WaitingMarkerEventPreResolved {
|
|
@@ -732,14 +756,14 @@ impl TryFrom<CommandType> for LocalActivityMachineEvents {
|
|
|
732
756
|
}
|
|
733
757
|
}
|
|
734
758
|
|
|
735
|
-
impl TryFrom<
|
|
759
|
+
impl TryFrom<HistEventData> for LocalActivityMachineEvents {
|
|
736
760
|
type Error = WFMachinesError;
|
|
737
761
|
|
|
738
|
-
fn try_from(e:
|
|
762
|
+
fn try_from(e: HistEventData) -> Result<Self, Self::Error> {
|
|
763
|
+
let e = e.event;
|
|
739
764
|
if e.event_type() != EventType::MarkerRecorded {
|
|
740
765
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
741
|
-
"Local activity machine cannot handle this event: {}"
|
|
742
|
-
e
|
|
766
|
+
"Local activity machine cannot handle this event: {e}"
|
|
743
767
|
)));
|
|
744
768
|
}
|
|
745
769
|
|
|
@@ -763,6 +787,28 @@ fn verify_marker_data_matches(
|
|
|
763
787
|
dat.marker_dat.seq, shared.attrs.seq
|
|
764
788
|
)));
|
|
765
789
|
}
|
|
790
|
+
// Here we use whether or not we were replaying when we _first invoked_ the LA, because we
|
|
791
|
+
// are always replaying when we see the marker recorded event, and that would make this check
|
|
792
|
+
// a bit pointless.
|
|
793
|
+
if shared.internal_flags.borrow_mut().try_use(
|
|
794
|
+
CoreInternalFlags::IdAndTypeDeterminismChecks,
|
|
795
|
+
!shared.replaying_when_invoked,
|
|
796
|
+
) {
|
|
797
|
+
if dat.marker_dat.activity_id != shared.attrs.activity_id {
|
|
798
|
+
return Err(WFMachinesError::Nondeterminism(format!(
|
|
799
|
+
"Activity id of recorded marker '{}' does not \
|
|
800
|
+
match activity id of local activity command '{}'",
|
|
801
|
+
dat.marker_dat.activity_id, shared.attrs.activity_id
|
|
802
|
+
)));
|
|
803
|
+
}
|
|
804
|
+
if dat.marker_dat.activity_type != shared.attrs.activity_type {
|
|
805
|
+
return Err(WFMachinesError::Nondeterminism(format!(
|
|
806
|
+
"Activity type of recorded marker '{}' does not \
|
|
807
|
+
match activity type of local activity command '{}'",
|
|
808
|
+
dat.marker_dat.activity_type, shared.attrs.activity_type
|
|
809
|
+
)));
|
|
810
|
+
}
|
|
811
|
+
}
|
|
766
812
|
|
|
767
813
|
Ok(())
|
|
768
814
|
}
|
|
@@ -805,10 +851,15 @@ mod tests {
|
|
|
805
851
|
temporal::api::{
|
|
806
852
|
command::v1::command, enums::v1::WorkflowTaskFailedCause, failure::v1::Failure,
|
|
807
853
|
},
|
|
854
|
+
DEFAULT_ACTIVITY_TYPE,
|
|
808
855
|
};
|
|
809
856
|
|
|
810
857
|
async fn la_wf(ctx: WfContext) -> WorkflowResult<()> {
|
|
811
|
-
ctx.local_activity(LocalActivityOptions
|
|
858
|
+
ctx.local_activity(LocalActivityOptions {
|
|
859
|
+
activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
|
|
860
|
+
..Default::default()
|
|
861
|
+
})
|
|
862
|
+
.await;
|
|
812
863
|
Ok(().into())
|
|
813
864
|
}
|
|
814
865
|
|
|
@@ -921,8 +972,16 @@ mod tests {
|
|
|
921
972
|
}
|
|
922
973
|
|
|
923
974
|
async fn two_la_wf(ctx: WfContext) -> WorkflowResult<()> {
|
|
924
|
-
ctx.local_activity(LocalActivityOptions
|
|
925
|
-
|
|
975
|
+
ctx.local_activity(LocalActivityOptions {
|
|
976
|
+
activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
|
|
977
|
+
..Default::default()
|
|
978
|
+
})
|
|
979
|
+
.await;
|
|
980
|
+
ctx.local_activity(LocalActivityOptions {
|
|
981
|
+
activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
|
|
982
|
+
..Default::default()
|
|
983
|
+
})
|
|
984
|
+
.await;
|
|
926
985
|
Ok(().into())
|
|
927
986
|
}
|
|
928
987
|
|
|
@@ -1015,8 +1074,14 @@ mod tests {
|
|
|
1015
1074
|
|
|
1016
1075
|
async fn two_la_wf_parallel(ctx: WfContext) -> WorkflowResult<()> {
|
|
1017
1076
|
tokio::join!(
|
|
1018
|
-
ctx.local_activity(LocalActivityOptions
|
|
1019
|
-
|
|
1077
|
+
ctx.local_activity(LocalActivityOptions {
|
|
1078
|
+
activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
|
|
1079
|
+
..Default::default()
|
|
1080
|
+
}),
|
|
1081
|
+
ctx.local_activity(LocalActivityOptions {
|
|
1082
|
+
activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
|
|
1083
|
+
..Default::default()
|
|
1084
|
+
})
|
|
1020
1085
|
);
|
|
1021
1086
|
Ok(().into())
|
|
1022
1087
|
}
|
|
@@ -1099,9 +1164,17 @@ mod tests {
|
|
|
1099
1164
|
}
|
|
1100
1165
|
|
|
1101
1166
|
async fn la_timer_la(ctx: WfContext) -> WorkflowResult<()> {
|
|
1102
|
-
ctx.local_activity(LocalActivityOptions
|
|
1167
|
+
ctx.local_activity(LocalActivityOptions {
|
|
1168
|
+
activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
|
|
1169
|
+
..Default::default()
|
|
1170
|
+
})
|
|
1171
|
+
.await;
|
|
1103
1172
|
ctx.timer(Duration::from_secs(5)).await;
|
|
1104
|
-
ctx.local_activity(LocalActivityOptions
|
|
1173
|
+
ctx.local_activity(LocalActivityOptions {
|
|
1174
|
+
activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
|
|
1175
|
+
..Default::default()
|
|
1176
|
+
})
|
|
1177
|
+
.await;
|
|
1105
1178
|
Ok(().into())
|
|
1106
1179
|
}
|
|
1107
1180
|
|
|
@@ -1342,6 +1415,7 @@ mod tests {
|
|
|
1342
1415
|
let func = WorkflowFunction::new(move |ctx| async move {
|
|
1343
1416
|
let la = ctx.local_activity(LocalActivityOptions {
|
|
1344
1417
|
cancel_type,
|
|
1418
|
+
activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
|
|
1345
1419
|
..Default::default()
|
|
1346
1420
|
});
|
|
1347
1421
|
ctx.timer(Duration::from_secs(1)).await;
|
|
@@ -1357,14 +1431,14 @@ mod tests {
|
|
|
1357
1431
|
let mut t = TestHistoryBuilder::default();
|
|
1358
1432
|
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
1359
1433
|
t.add_full_wf_task();
|
|
1360
|
-
let timer_started_event_id = t.
|
|
1434
|
+
let timer_started_event_id = t.add_by_type(EventType::TimerStarted);
|
|
1361
1435
|
t.add_timer_fired(timer_started_event_id, "1".to_string());
|
|
1362
1436
|
t.add_full_wf_task();
|
|
1363
1437
|
if cancel_type != ActivityCancellationType::WaitCancellationCompleted {
|
|
1364
1438
|
// With non-wait cancels, the cancel is immediate
|
|
1365
1439
|
t.add_local_activity_cancel_marker(1, "1");
|
|
1366
1440
|
}
|
|
1367
|
-
let timer_started_event_id = t.
|
|
1441
|
+
let timer_started_event_id = t.add_by_type(EventType::TimerStarted);
|
|
1368
1442
|
if cancel_type == ActivityCancellationType::WaitCancellationCompleted {
|
|
1369
1443
|
// With wait cancels, the cancel marker is not recorded until activity reports.
|
|
1370
1444
|
t.add_local_activity_cancel_marker(1, "1");
|
|
@@ -1408,8 +1482,9 @@ mod tests {
|
|
|
1408
1482
|
assert_eq!(commands[1].command_type, CommandType::StartTimer as i32);
|
|
1409
1483
|
}
|
|
1410
1484
|
|
|
1411
|
-
if replay {
|
|
1412
|
-
wfm.get_next_activation().await.unwrap()
|
|
1485
|
+
let commands = if replay {
|
|
1486
|
+
wfm.get_next_activation().await.unwrap();
|
|
1487
|
+
wfm.get_server_commands().commands
|
|
1413
1488
|
} else {
|
|
1414
1489
|
// On non replay, there's an additional activation, because completing with the cancel
|
|
1415
1490
|
// wants to wake up the workflow to see if resolving the LA as cancelled did anything.
|
|
@@ -1434,11 +1509,11 @@ mod tests {
|
|
|
1434
1509
|
|
|
1435
1510
|
wfm.new_history(t.get_history_info(3).unwrap().into())
|
|
1436
1511
|
.await
|
|
1437
|
-
.unwrap()
|
|
1512
|
+
.unwrap();
|
|
1513
|
+
wfm.get_next_activation().await.unwrap();
|
|
1514
|
+
wfm.get_server_commands().commands
|
|
1438
1515
|
};
|
|
1439
1516
|
|
|
1440
|
-
wfm.get_next_activation().await.unwrap();
|
|
1441
|
-
let commands = wfm.get_server_commands().commands;
|
|
1442
1517
|
assert_eq!(commands.len(), 1);
|
|
1443
1518
|
assert_eq!(
|
|
1444
1519
|
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;
|
|
@@ -73,7 +73,7 @@ enum Machines {
|
|
|
73
73
|
///
|
|
74
74
|
/// Formerly known as `EntityStateMachine` in Java.
|
|
75
75
|
#[enum_dispatch::enum_dispatch(Machines)]
|
|
76
|
-
trait TemporalStateMachine
|
|
76
|
+
trait TemporalStateMachine {
|
|
77
77
|
fn handle_command(
|
|
78
78
|
&mut self,
|
|
79
79
|
command_type: CommandType,
|
|
@@ -88,8 +88,7 @@ trait TemporalStateMachine: Send {
|
|
|
88
88
|
/// to update the overall state of the workflow. EX: To issue outgoing WF activations.
|
|
89
89
|
fn handle_event(
|
|
90
90
|
&mut self,
|
|
91
|
-
event:
|
|
92
|
-
has_next_event: bool,
|
|
91
|
+
event: HistEventData,
|
|
93
92
|
) -> Result<Vec<MachineResponse>, WFMachinesError>;
|
|
94
93
|
|
|
95
94
|
/// Attempt to cancel the command associated with this state machine, if it is cancellable
|
|
@@ -108,9 +107,9 @@ trait TemporalStateMachine: Send {
|
|
|
108
107
|
|
|
109
108
|
impl<SM> TemporalStateMachine for SM
|
|
110
109
|
where
|
|
111
|
-
SM: StateMachine + WFMachinesAdapter + Cancellable + OnEventWrapper + Clone +
|
|
112
|
-
<SM as StateMachine>::Event: TryFrom<
|
|
113
|
-
WFMachinesError: From<<<SM as StateMachine>::Event as TryFrom<
|
|
110
|
+
SM: StateMachine + WFMachinesAdapter + Cancellable + OnEventWrapper + Clone + 'static,
|
|
111
|
+
<SM as StateMachine>::Event: TryFrom<HistEventData> + TryFrom<CommandType> + Display,
|
|
112
|
+
WFMachinesError: From<<<SM as StateMachine>::Event as TryFrom<HistEventData>>::Error>,
|
|
114
113
|
<SM as StateMachine>::Command: Debug + Display,
|
|
115
114
|
<SM as StateMachine>::State: Display,
|
|
116
115
|
<SM as StateMachine>::Error: Into<WFMachinesError> + 'static + Send + Sync,
|
|
@@ -152,21 +151,19 @@ where
|
|
|
152
151
|
|
|
153
152
|
fn handle_event(
|
|
154
153
|
&mut self,
|
|
155
|
-
|
|
156
|
-
has_next_event: bool,
|
|
154
|
+
event_dat: HistEventData,
|
|
157
155
|
) -> Result<Vec<MachineResponse>, WFMachinesError> {
|
|
158
156
|
trace!(
|
|
159
|
-
event = %event,
|
|
157
|
+
event = %event_dat.event,
|
|
160
158
|
machine_name = %self.name(),
|
|
161
159
|
state = %self.state(),
|
|
162
160
|
"handling event"
|
|
163
161
|
);
|
|
164
162
|
let event_info = EventInfo {
|
|
165
|
-
event_id: event.event_id,
|
|
166
|
-
event_type: event.event_type(),
|
|
167
|
-
has_next_event,
|
|
163
|
+
event_id: event_dat.event.event_id,
|
|
164
|
+
event_type: event_dat.event.event_type(),
|
|
168
165
|
};
|
|
169
|
-
let converted_event: <Self as StateMachine>::Event =
|
|
166
|
+
let converted_event: <Self as StateMachine>::Event = event_dat.try_into()?;
|
|
170
167
|
|
|
171
168
|
match OnEventWrapper::on_event_mut(self, converted_event) {
|
|
172
169
|
Ok(c) => process_machine_commands(self, c, Some(event_info)),
|
|
@@ -217,7 +214,7 @@ where
|
|
|
217
214
|
<SM as StateMachine>::State: Display,
|
|
218
215
|
{
|
|
219
216
|
if !commands.is_empty() {
|
|
220
|
-
|
|
217
|
+
trace!(commands=%commands.display(), state=%machine.state(),
|
|
221
218
|
machine_name=%TemporalStateMachine::name(machine), "Machine produced commands");
|
|
222
219
|
}
|
|
223
220
|
let mut machine_responses = vec![];
|
|
@@ -245,11 +242,22 @@ trait WFMachinesAdapter: StateMachine {
|
|
|
245
242
|
fn matches_event(&self, event: &HistoryEvent) -> bool;
|
|
246
243
|
}
|
|
247
244
|
|
|
245
|
+
/// Wraps a history event with extra relevant data that a machine might care about while the event
|
|
246
|
+
/// is being applied to it.
|
|
247
|
+
#[derive(Debug, derive_more::Display)]
|
|
248
|
+
#[display(fmt = "{event}")]
|
|
249
|
+
struct HistEventData {
|
|
250
|
+
event: HistoryEvent,
|
|
251
|
+
/// Is the current workflow task under replay or not during application of this event?
|
|
252
|
+
replaying: bool,
|
|
253
|
+
/// Is the current workflow task the last task in history?
|
|
254
|
+
current_task_is_last_in_history: bool,
|
|
255
|
+
}
|
|
256
|
+
|
|
248
257
|
#[derive(Debug, Copy, Clone)]
|
|
249
258
|
struct EventInfo {
|
|
250
259
|
event_id: i64,
|
|
251
260
|
event_type: EventType,
|
|
252
|
-
has_next_event: bool,
|
|
253
261
|
}
|
|
254
262
|
|
|
255
263
|
trait Cancellable: StateMachine {
|
data/bridge/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, HistEventData, 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,
|
|
@@ -74,10 +74,11 @@ impl WFMachinesAdapter for ModifyWorkflowPropertiesMachine {
|
|
|
74
74
|
|
|
75
75
|
impl Cancellable for ModifyWorkflowPropertiesMachine {}
|
|
76
76
|
|
|
77
|
-
impl TryFrom<
|
|
77
|
+
impl TryFrom<HistEventData> for ModifyWorkflowPropertiesMachineEvents {
|
|
78
78
|
type Error = WFMachinesError;
|
|
79
79
|
|
|
80
|
-
fn try_from(e:
|
|
80
|
+
fn try_from(e: HistEventData) -> Result<Self, Self::Error> {
|
|
81
|
+
let e = e.event;
|
|
81
82
|
match e.event_type() {
|
|
82
83
|
EventType::WorkflowPropertiesModified => {
|
|
83
84
|
Ok(ModifyWorkflowPropertiesMachineEvents::CommandRecorded)
|