@temporalio/core-bridge 1.6.0 → 1.7.1
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 +520 -456
- package/lib/index.d.ts +8 -6
- package/lib/index.js.map +1 -1
- package/package.json +8 -3
- 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/docker/Dockerfile +2 -2
- package/sdk-core/.buildkite/docker/docker-compose.yaml +1 -1
- package/sdk-core/.buildkite/pipeline.yml +1 -1
- package/sdk-core/.github/workflows/heavy.yml +1 -0
- package/sdk-core/README.md +13 -7
- package/sdk-core/client/src/lib.rs +27 -9
- package/sdk-core/client/src/metrics.rs +17 -8
- package/sdk-core/client/src/raw.rs +3 -3
- package/sdk-core/core/Cargo.toml +3 -4
- package/sdk-core/core/src/abstractions/take_cell.rs +28 -0
- package/sdk-core/core/src/abstractions.rs +197 -18
- package/sdk-core/core/src/core_tests/activity_tasks.rs +137 -45
- package/sdk-core/core/src/core_tests/child_workflows.rs +6 -5
- package/sdk-core/core/src/core_tests/determinism.rs +212 -2
- package/sdk-core/core/src/core_tests/local_activities.rs +183 -36
- package/sdk-core/core/src/core_tests/queries.rs +32 -14
- package/sdk-core/core/src/core_tests/workers.rs +8 -5
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +340 -51
- package/sdk-core/core/src/ephemeral_server/mod.rs +110 -8
- package/sdk-core/core/src/internal_flags.rs +141 -0
- package/sdk-core/core/src/lib.rs +14 -9
- package/sdk-core/core/src/replay/mod.rs +16 -27
- package/sdk-core/core/src/telemetry/metrics.rs +69 -35
- package/sdk-core/core/src/telemetry/mod.rs +38 -14
- package/sdk-core/core/src/telemetry/prometheus_server.rs +19 -13
- package/sdk-core/core/src/test_help/mod.rs +65 -13
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +119 -160
- package/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +89 -0
- package/sdk-core/core/src/worker/activities/local_activities.rs +122 -6
- package/sdk-core/core/src/worker/activities.rs +347 -173
- package/sdk-core/core/src/worker/client/mocks.rs +22 -2
- package/sdk-core/core/src/worker/client.rs +18 -2
- package/sdk-core/core/src/worker/mod.rs +137 -44
- package/sdk-core/core/src/worker/workflow/history_update.rs +132 -51
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +207 -166
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +6 -7
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +6 -7
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +157 -82
- package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +12 -12
- package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +6 -7
- package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +13 -15
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +170 -60
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +24 -16
- package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +6 -8
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +320 -204
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +10 -13
- package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +15 -23
- package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +187 -46
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +237 -111
- package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +13 -13
- package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +10 -6
- package/sdk-core/core/src/worker/workflow/managed_run.rs +81 -62
- package/sdk-core/core/src/worker/workflow/mod.rs +341 -79
- package/sdk-core/core/src/worker/workflow/run_cache.rs +18 -11
- package/sdk-core/core/src/worker/workflow/wft_extraction.rs +15 -3
- package/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +2 -0
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +75 -52
- package/sdk-core/core-api/Cargo.toml +0 -1
- package/sdk-core/core-api/src/lib.rs +13 -7
- package/sdk-core/core-api/src/telemetry.rs +4 -6
- package/sdk-core/core-api/src/worker.rs +5 -0
- package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +80 -55
- package/sdk-core/fsm/rustfsm_trait/src/lib.rs +22 -68
- package/sdk-core/histories/ends_empty_wft_complete.bin +0 -0
- package/sdk-core/histories/old_change_marker_format.bin +0 -0
- package/sdk-core/protos/api_upstream/.github/CODEOWNERS +2 -1
- package/sdk-core/protos/api_upstream/Makefile +1 -1
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +5 -17
- package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +11 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +1 -6
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +6 -6
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +5 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +22 -6
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +48 -19
- package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +2 -0
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +3 -0
- package/sdk-core/protos/api_upstream/temporal/api/{enums/v1/interaction_type.proto → protocol/v1/message.proto} +29 -11
- package/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +63 -0
- package/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +111 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +59 -28
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +2 -2
- package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +7 -8
- package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +10 -7
- package/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +19 -30
- package/sdk-core/protos/local/temporal/sdk/core/common/common.proto +1 -0
- package/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +1 -0
- package/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +8 -0
- package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +65 -60
- package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +85 -84
- package/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +9 -3
- package/sdk-core/sdk/Cargo.toml +1 -1
- package/sdk-core/sdk/src/lib.rs +21 -5
- package/sdk-core/sdk/src/workflow_context/options.rs +7 -1
- package/sdk-core/sdk/src/workflow_context.rs +24 -17
- package/sdk-core/sdk/src/workflow_future.rs +9 -3
- package/sdk-core/sdk-core-protos/src/history_builder.rs +114 -89
- package/sdk-core/sdk-core-protos/src/history_info.rs +6 -1
- package/sdk-core/sdk-core-protos/src/lib.rs +205 -64
- package/sdk-core/test-utils/src/canned_histories.rs +106 -296
- package/sdk-core/test-utils/src/lib.rs +32 -5
- package/sdk-core/tests/heavy_tests.rs +10 -43
- package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +25 -3
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +5 -3
- package/sdk-core/tests/integ_tests/metrics_tests.rs +218 -16
- package/sdk-core/tests/integ_tests/polling_tests.rs +3 -8
- package/sdk-core/tests/integ_tests/queries_tests.rs +4 -2
- package/sdk-core/tests/integ_tests/visibility_tests.rs +34 -23
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +97 -81
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -0
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -0
- package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +80 -3
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +5 -1
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +1 -0
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +25 -3
- package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +2 -4
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +30 -0
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +64 -0
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -0
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +4 -0
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +3 -1
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +7 -2
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +6 -7
- package/sdk-core/tests/integ_tests/workflow_tests.rs +8 -8
- package/sdk-core/tests/main.rs +16 -25
- package/sdk-core/tests/runner.rs +11 -9
- package/src/conversions.rs +14 -8
- package/src/runtime.rs +9 -8
- package/ts/index.ts +8 -6
- package/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +0 -87
|
@@ -3,8 +3,15 @@ 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::{
|
|
10
|
+
machines::{activity_state_machine::activity_fail_info, HistEventData},
|
|
11
|
+
InternalFlagsRef, OutgoingJob,
|
|
12
|
+
},
|
|
13
|
+
LocalActivityExecutionResult,
|
|
14
|
+
},
|
|
8
15
|
};
|
|
9
16
|
use rustfsm::{fsm, MachineError, StateMachine, TransitionResult};
|
|
10
17
|
use std::{
|
|
@@ -24,8 +31,8 @@ use temporal_sdk_core_protos::{
|
|
|
24
31
|
},
|
|
25
32
|
temporal::api::{
|
|
26
33
|
command::v1::{Command, RecordMarkerCommandAttributes},
|
|
27
|
-
enums::v1::{CommandType, EventType},
|
|
28
|
-
failure::v1::failure::FailureInfo,
|
|
34
|
+
enums::v1::{CommandType, EventType, RetryState},
|
|
35
|
+
failure::v1::{failure::FailureInfo, Failure},
|
|
29
36
|
history::v1::HistoryEvent,
|
|
30
37
|
},
|
|
31
38
|
utilities::TryIntoOrNone,
|
|
@@ -113,7 +120,12 @@ impl From<CompleteLocalActivityData> for ResolveDat {
|
|
|
113
120
|
result: match d.result {
|
|
114
121
|
Ok(res) => LocalActivityExecutionResult::Completed(Success { result: Some(res) }),
|
|
115
122
|
Err(fail) => {
|
|
116
|
-
if matches!(fail.failure_info, Some(FailureInfo::CanceledFailureInfo(_)))
|
|
123
|
+
if matches!(fail.failure_info, Some(FailureInfo::CanceledFailureInfo(_)))
|
|
124
|
+
|| matches!(
|
|
125
|
+
fail.cause.as_deref().and_then(|f| f.failure_info.as_ref()),
|
|
126
|
+
Some(FailureInfo::CanceledFailureInfo(_))
|
|
127
|
+
)
|
|
128
|
+
{
|
|
117
129
|
LocalActivityExecutionResult::Cancelled(Cancellation {
|
|
118
130
|
failure: Some(fail),
|
|
119
131
|
})
|
|
@@ -141,6 +153,7 @@ pub(super) fn new_local_activity(
|
|
|
141
153
|
replaying_when_invoked: bool,
|
|
142
154
|
maybe_pre_resolved: Option<ResolveDat>,
|
|
143
155
|
wf_time: Option<SystemTime>,
|
|
156
|
+
internal_flags: InternalFlagsRef,
|
|
144
157
|
) -> Result<(LocalActivityMachine, Vec<MachineResponse>), WFMachinesError> {
|
|
145
158
|
let initial_state = if replaying_when_invoked {
|
|
146
159
|
if let Some(dat) = maybe_pre_resolved {
|
|
@@ -162,14 +175,15 @@ pub(super) fn new_local_activity(
|
|
|
162
175
|
.original_schedule_time
|
|
163
176
|
.get_or_insert(SystemTime::now());
|
|
164
177
|
|
|
165
|
-
let mut machine = LocalActivityMachine
|
|
166
|
-
|
|
167
|
-
|
|
178
|
+
let mut machine = LocalActivityMachine::from_parts(
|
|
179
|
+
initial_state,
|
|
180
|
+
SharedState {
|
|
168
181
|
attrs,
|
|
169
182
|
replaying_when_invoked,
|
|
170
183
|
wf_time_when_started: wf_time,
|
|
184
|
+
internal_flags,
|
|
171
185
|
},
|
|
172
|
-
|
|
186
|
+
);
|
|
173
187
|
|
|
174
188
|
let mut res = OnEventWrapper::on_event_mut(&mut machine, LocalActivityMachineEvents::Schedule)
|
|
175
189
|
.expect("Scheduling local activities doesn't fail");
|
|
@@ -193,13 +207,13 @@ impl LocalActivityMachine {
|
|
|
193
207
|
///
|
|
194
208
|
/// Attempting the check in any other state likely means a bug in the SDK.
|
|
195
209
|
pub(super) fn marker_should_get_special_handling(&self) -> Result<bool, WFMachinesError> {
|
|
196
|
-
match
|
|
210
|
+
match self.state() {
|
|
197
211
|
LocalActivityMachineState::ResultNotified(_) => Ok(false),
|
|
198
212
|
LocalActivityMachineState::WaitingMarkerEvent(_) => Ok(true),
|
|
199
213
|
LocalActivityMachineState::WaitingMarkerEventPreResolved(_) => Ok(true),
|
|
200
214
|
_ => Err(WFMachinesError::Fatal(format!(
|
|
201
215
|
"Attempted to check for LA marker handling in invalid state {}",
|
|
202
|
-
self.state
|
|
216
|
+
self.state()
|
|
203
217
|
))),
|
|
204
218
|
}
|
|
205
219
|
}
|
|
@@ -207,7 +221,10 @@ impl LocalActivityMachine {
|
|
|
207
221
|
/// Returns true if the machine will willingly accept data from a marker in its current state.
|
|
208
222
|
/// IE: Calling [Self::try_resolve_with_dat] makes sense.
|
|
209
223
|
pub(super) fn will_accept_resolve_marker(&self) -> bool {
|
|
210
|
-
matches!(
|
|
224
|
+
matches!(
|
|
225
|
+
self.state(),
|
|
226
|
+
LocalActivityMachineState::WaitingMarkerEvent(_)
|
|
227
|
+
)
|
|
211
228
|
}
|
|
212
229
|
|
|
213
230
|
/// Must be called if the workflow encounters a non-replay workflow task
|
|
@@ -303,6 +320,7 @@ pub(super) struct SharedState {
|
|
|
303
320
|
attrs: ValidScheduleLA,
|
|
304
321
|
replaying_when_invoked: bool,
|
|
305
322
|
wf_time_when_started: Option<SystemTime>,
|
|
323
|
+
internal_flags: InternalFlagsRef,
|
|
306
324
|
}
|
|
307
325
|
|
|
308
326
|
impl SharedState {
|
|
@@ -344,9 +362,11 @@ pub(super) struct Executing {}
|
|
|
344
362
|
impl Executing {
|
|
345
363
|
pub(super) fn on_schedule(
|
|
346
364
|
self,
|
|
347
|
-
dat: SharedState,
|
|
365
|
+
dat: &mut SharedState,
|
|
348
366
|
) -> LocalActivityMachineTransition<RequestSent> {
|
|
349
|
-
TransitionResult::commands([LocalActivityCommand::RequestActivityExecution(
|
|
367
|
+
TransitionResult::commands([LocalActivityCommand::RequestActivityExecution(
|
|
368
|
+
dat.attrs.clone(),
|
|
369
|
+
)])
|
|
350
370
|
}
|
|
351
371
|
}
|
|
352
372
|
|
|
@@ -456,7 +476,7 @@ impl RequestSent {
|
|
|
456
476
|
|
|
457
477
|
fn on_no_wait_cancel(
|
|
458
478
|
self,
|
|
459
|
-
shared: SharedState,
|
|
479
|
+
shared: &mut SharedState,
|
|
460
480
|
cancel_type: ActivityCancellationType,
|
|
461
481
|
) -> LocalActivityMachineTransition<MarkerCommandCreated> {
|
|
462
482
|
let mut cmds = vec![];
|
|
@@ -495,7 +515,7 @@ pub(super) struct ResultNotified {
|
|
|
495
515
|
impl ResultNotified {
|
|
496
516
|
pub(super) fn on_marker_recorded(
|
|
497
517
|
self,
|
|
498
|
-
shared: SharedState,
|
|
518
|
+
shared: &mut SharedState,
|
|
499
519
|
dat: CompleteLocalActivityData,
|
|
500
520
|
) -> LocalActivityMachineTransition<MarkerCommandRecorded> {
|
|
501
521
|
if self.result_type == ResultType::Completed && dat.result.is_err() {
|
|
@@ -510,7 +530,7 @@ impl ResultNotified {
|
|
|
510
530
|
shared.attrs.seq
|
|
511
531
|
)));
|
|
512
532
|
}
|
|
513
|
-
verify_marker_dat!(
|
|
533
|
+
verify_marker_dat!(shared, &dat, TransitionResult::default())
|
|
514
534
|
}
|
|
515
535
|
}
|
|
516
536
|
|
|
@@ -522,11 +542,11 @@ pub(super) struct WaitingMarkerEvent {
|
|
|
522
542
|
impl WaitingMarkerEvent {
|
|
523
543
|
pub(super) fn on_marker_recorded(
|
|
524
544
|
self,
|
|
525
|
-
shared: SharedState,
|
|
545
|
+
shared: &mut SharedState,
|
|
526
546
|
dat: CompleteLocalActivityData,
|
|
527
547
|
) -> LocalActivityMachineTransition<MarkerCommandRecorded> {
|
|
528
548
|
verify_marker_dat!(
|
|
529
|
-
|
|
549
|
+
shared,
|
|
530
550
|
&dat,
|
|
531
551
|
TransitionResult::commands(if self.already_resolved {
|
|
532
552
|
vec![]
|
|
@@ -548,17 +568,13 @@ impl WaitingMarkerEvent {
|
|
|
548
568
|
}
|
|
549
569
|
pub(super) fn on_started_non_replay_wft(
|
|
550
570
|
self,
|
|
551
|
-
|
|
571
|
+
dat: &mut SharedState,
|
|
552
572
|
) -> LocalActivityMachineTransition<RequestSent> {
|
|
553
573
|
// We aren't really "replaying" anymore for our purposes, and want to record the marker.
|
|
554
574
|
dat.replaying_when_invoked = false;
|
|
555
|
-
TransitionResult::
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
)],
|
|
559
|
-
RequestSent::default(),
|
|
560
|
-
dat,
|
|
561
|
-
)
|
|
575
|
+
TransitionResult::commands([LocalActivityCommand::RequestActivityExecution(
|
|
576
|
+
dat.attrs.clone(),
|
|
577
|
+
)])
|
|
562
578
|
}
|
|
563
579
|
|
|
564
580
|
fn on_cancel_requested(self) -> LocalActivityMachineTransition<WaitingMarkerEvent> {
|
|
@@ -582,10 +598,10 @@ pub(super) struct WaitingMarkerEventPreResolved {}
|
|
|
582
598
|
impl WaitingMarkerEventPreResolved {
|
|
583
599
|
pub(super) fn on_marker_recorded(
|
|
584
600
|
self,
|
|
585
|
-
shared: SharedState,
|
|
601
|
+
shared: &mut SharedState,
|
|
586
602
|
dat: CompleteLocalActivityData,
|
|
587
603
|
) -> LocalActivityMachineTransition<MarkerCommandRecorded> {
|
|
588
|
-
verify_marker_dat!(
|
|
604
|
+
verify_marker_dat!(shared, &dat, TransitionResult::default())
|
|
589
605
|
}
|
|
590
606
|
}
|
|
591
607
|
|
|
@@ -667,8 +683,61 @@ impl WFMachinesAdapter for LocalActivityMachine {
|
|
|
667
683
|
),
|
|
668
684
|
}
|
|
669
685
|
} else {
|
|
670
|
-
|
|
686
|
+
// Cancels and timeouts are to be wrapped with an activity failure
|
|
687
|
+
macro_rules! wrap_fail {
|
|
688
|
+
($me:ident, $fail:ident, $msg:expr, $info:pat) => {
|
|
689
|
+
let mut fail = $fail.failure.take();
|
|
690
|
+
let fail_info = fail.as_ref().and_then(|f| f.failure_info.as_ref());
|
|
691
|
+
if matches!(fail_info, Some($info)) {
|
|
692
|
+
fail = Some(Failure {
|
|
693
|
+
message: $msg,
|
|
694
|
+
cause: fail.map(Box::new),
|
|
695
|
+
failure_info: Some(activity_fail_info(
|
|
696
|
+
$me.shared_state.attrs.activity_type.clone(),
|
|
697
|
+
$me.shared_state.attrs.activity_id.clone(),
|
|
698
|
+
None,
|
|
699
|
+
RetryState::CancelRequested,
|
|
700
|
+
0,
|
|
701
|
+
0,
|
|
702
|
+
)),
|
|
703
|
+
..Default::default()
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
$fail.failure = fail;
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
match result {
|
|
710
|
+
LocalActivityExecutionResult::Completed(c) => ActivityResolution {
|
|
711
|
+
status: Some(c.into()),
|
|
712
|
+
},
|
|
713
|
+
LocalActivityExecutionResult::Failed(f) => ActivityResolution {
|
|
714
|
+
status: Some(f.into()),
|
|
715
|
+
},
|
|
716
|
+
LocalActivityExecutionResult::TimedOut(mut failure) => {
|
|
717
|
+
wrap_fail!(
|
|
718
|
+
self,
|
|
719
|
+
failure,
|
|
720
|
+
"Local Activity timed out".to_string(),
|
|
721
|
+
FailureInfo::TimeoutFailureInfo(_)
|
|
722
|
+
);
|
|
723
|
+
ActivityResolution {
|
|
724
|
+
status: Some(failure.into()),
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
LocalActivityExecutionResult::Cancelled(mut cancel) => {
|
|
728
|
+
wrap_fail!(
|
|
729
|
+
self,
|
|
730
|
+
cancel,
|
|
731
|
+
"Local Activity cancelled".to_string(),
|
|
732
|
+
FailureInfo::CanceledFailureInfo(_)
|
|
733
|
+
);
|
|
734
|
+
ActivityResolution {
|
|
735
|
+
status: Some(cancel.into()),
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
671
739
|
};
|
|
740
|
+
|
|
672
741
|
let mut responses = vec![
|
|
673
742
|
MachineResponse::PushWFJob(OutgoingJob {
|
|
674
743
|
variant: ResolveActivity {
|
|
@@ -749,10 +818,11 @@ impl TryFrom<CommandType> for LocalActivityMachineEvents {
|
|
|
749
818
|
}
|
|
750
819
|
}
|
|
751
820
|
|
|
752
|
-
impl TryFrom<
|
|
821
|
+
impl TryFrom<HistEventData> for LocalActivityMachineEvents {
|
|
753
822
|
type Error = WFMachinesError;
|
|
754
823
|
|
|
755
|
-
fn try_from(e:
|
|
824
|
+
fn try_from(e: HistEventData) -> Result<Self, Self::Error> {
|
|
825
|
+
let e = e.event;
|
|
756
826
|
if e.event_type() != EventType::MarkerRecorded {
|
|
757
827
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
758
828
|
"Local activity machine cannot handle this event: {e}"
|
|
@@ -779,26 +849,30 @@ fn verify_marker_data_matches(
|
|
|
779
849
|
dat.marker_dat.seq, shared.attrs.seq
|
|
780
850
|
)));
|
|
781
851
|
}
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
852
|
+
// Here we use whether or not we were replaying when we _first invoked_ the LA, because we
|
|
853
|
+
// are always replaying when we see the marker recorded event, and that would make this check
|
|
854
|
+
// a bit pointless.
|
|
855
|
+
if shared.internal_flags.borrow_mut().try_use(
|
|
856
|
+
CoreInternalFlags::IdAndTypeDeterminismChecks,
|
|
857
|
+
!shared.replaying_when_invoked,
|
|
858
|
+
) {
|
|
859
|
+
if dat.marker_dat.activity_id != shared.attrs.activity_id {
|
|
860
|
+
return Err(WFMachinesError::Nondeterminism(format!(
|
|
861
|
+
"Activity id of recorded marker '{}' does not \
|
|
862
|
+
match activity id of local activity command '{}'",
|
|
863
|
+
dat.marker_dat.activity_id, shared.attrs.activity_id
|
|
864
|
+
)));
|
|
865
|
+
}
|
|
866
|
+
if dat.marker_dat.activity_type != shared.attrs.activity_type {
|
|
867
|
+
return Err(WFMachinesError::Nondeterminism(format!(
|
|
868
|
+
"Activity type of recorded marker '{}' does not \
|
|
869
|
+
match activity type of local activity command '{}'",
|
|
870
|
+
dat.marker_dat.activity_type, shared.attrs.activity_type
|
|
871
|
+
)));
|
|
800
872
|
}
|
|
801
873
|
}
|
|
874
|
+
|
|
875
|
+
Ok(())
|
|
802
876
|
}
|
|
803
877
|
|
|
804
878
|
#[cfg(test)]
|
|
@@ -816,15 +890,19 @@ mod tests {
|
|
|
816
890
|
coresdk::{
|
|
817
891
|
activity_result::ActivityExecutionResult,
|
|
818
892
|
workflow_activation::{workflow_activation_job, WorkflowActivationJob},
|
|
819
|
-
workflow_commands::ActivityCancellationType::WaitCancellationCompleted,
|
|
820
893
|
},
|
|
821
894
|
temporal::api::{
|
|
822
895
|
command::v1::command, enums::v1::WorkflowTaskFailedCause, failure::v1::Failure,
|
|
823
896
|
},
|
|
897
|
+
DEFAULT_ACTIVITY_TYPE,
|
|
824
898
|
};
|
|
825
899
|
|
|
826
900
|
async fn la_wf(ctx: WfContext) -> WorkflowResult<()> {
|
|
827
|
-
ctx.local_activity(LocalActivityOptions
|
|
901
|
+
ctx.local_activity(LocalActivityOptions {
|
|
902
|
+
activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
|
|
903
|
+
..Default::default()
|
|
904
|
+
})
|
|
905
|
+
.await;
|
|
828
906
|
Ok(().into())
|
|
829
907
|
}
|
|
830
908
|
|
|
@@ -937,8 +1015,16 @@ mod tests {
|
|
|
937
1015
|
}
|
|
938
1016
|
|
|
939
1017
|
async fn two_la_wf(ctx: WfContext) -> WorkflowResult<()> {
|
|
940
|
-
ctx.local_activity(LocalActivityOptions
|
|
941
|
-
|
|
1018
|
+
ctx.local_activity(LocalActivityOptions {
|
|
1019
|
+
activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
|
|
1020
|
+
..Default::default()
|
|
1021
|
+
})
|
|
1022
|
+
.await;
|
|
1023
|
+
ctx.local_activity(LocalActivityOptions {
|
|
1024
|
+
activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
|
|
1025
|
+
..Default::default()
|
|
1026
|
+
})
|
|
1027
|
+
.await;
|
|
942
1028
|
Ok(().into())
|
|
943
1029
|
}
|
|
944
1030
|
|
|
@@ -1031,8 +1117,14 @@ mod tests {
|
|
|
1031
1117
|
|
|
1032
1118
|
async fn two_la_wf_parallel(ctx: WfContext) -> WorkflowResult<()> {
|
|
1033
1119
|
tokio::join!(
|
|
1034
|
-
ctx.local_activity(LocalActivityOptions
|
|
1035
|
-
|
|
1120
|
+
ctx.local_activity(LocalActivityOptions {
|
|
1121
|
+
activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
|
|
1122
|
+
..Default::default()
|
|
1123
|
+
}),
|
|
1124
|
+
ctx.local_activity(LocalActivityOptions {
|
|
1125
|
+
activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
|
|
1126
|
+
..Default::default()
|
|
1127
|
+
})
|
|
1036
1128
|
);
|
|
1037
1129
|
Ok(().into())
|
|
1038
1130
|
}
|
|
@@ -1115,9 +1207,17 @@ mod tests {
|
|
|
1115
1207
|
}
|
|
1116
1208
|
|
|
1117
1209
|
async fn la_timer_la(ctx: WfContext) -> WorkflowResult<()> {
|
|
1118
|
-
ctx.local_activity(LocalActivityOptions
|
|
1210
|
+
ctx.local_activity(LocalActivityOptions {
|
|
1211
|
+
activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
|
|
1212
|
+
..Default::default()
|
|
1213
|
+
})
|
|
1214
|
+
.await;
|
|
1119
1215
|
ctx.timer(Duration::from_secs(5)).await;
|
|
1120
|
-
ctx.local_activity(LocalActivityOptions
|
|
1216
|
+
ctx.local_activity(LocalActivityOptions {
|
|
1217
|
+
activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
|
|
1218
|
+
..Default::default()
|
|
1219
|
+
})
|
|
1220
|
+
.await;
|
|
1121
1221
|
Ok(().into())
|
|
1122
1222
|
}
|
|
1123
1223
|
|
|
@@ -1358,6 +1458,7 @@ mod tests {
|
|
|
1358
1458
|
let func = WorkflowFunction::new(move |ctx| async move {
|
|
1359
1459
|
let la = ctx.local_activity(LocalActivityOptions {
|
|
1360
1460
|
cancel_type,
|
|
1461
|
+
activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
|
|
1361
1462
|
..Default::default()
|
|
1362
1463
|
});
|
|
1363
1464
|
ctx.timer(Duration::from_secs(1)).await;
|
|
@@ -1367,20 +1468,29 @@ mod tests {
|
|
|
1367
1468
|
ctx.timer(Duration::from_secs(1)).await;
|
|
1368
1469
|
let resolution = la.await;
|
|
1369
1470
|
assert!(resolution.cancelled());
|
|
1471
|
+
let rfail = resolution.unwrap_failure();
|
|
1472
|
+
assert_matches!(
|
|
1473
|
+
rfail.failure_info,
|
|
1474
|
+
Some(FailureInfo::ActivityFailureInfo(_))
|
|
1475
|
+
);
|
|
1476
|
+
assert_matches!(
|
|
1477
|
+
rfail.cause.unwrap().failure_info,
|
|
1478
|
+
Some(FailureInfo::CanceledFailureInfo(_))
|
|
1479
|
+
);
|
|
1370
1480
|
Ok(().into())
|
|
1371
1481
|
});
|
|
1372
1482
|
|
|
1373
1483
|
let mut t = TestHistoryBuilder::default();
|
|
1374
1484
|
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
1375
1485
|
t.add_full_wf_task();
|
|
1376
|
-
let timer_started_event_id = t.
|
|
1486
|
+
let timer_started_event_id = t.add_by_type(EventType::TimerStarted);
|
|
1377
1487
|
t.add_timer_fired(timer_started_event_id, "1".to_string());
|
|
1378
1488
|
t.add_full_wf_task();
|
|
1379
1489
|
if cancel_type != ActivityCancellationType::WaitCancellationCompleted {
|
|
1380
1490
|
// With non-wait cancels, the cancel is immediate
|
|
1381
1491
|
t.add_local_activity_cancel_marker(1, "1");
|
|
1382
1492
|
}
|
|
1383
|
-
let timer_started_event_id = t.
|
|
1493
|
+
let timer_started_event_id = t.add_by_type(EventType::TimerStarted);
|
|
1384
1494
|
if cancel_type == ActivityCancellationType::WaitCancellationCompleted {
|
|
1385
1495
|
// With wait cancels, the cancel marker is not recorded until activity reports.
|
|
1386
1496
|
t.add_local_activity_cancel_marker(1, "1");
|
|
@@ -1434,7 +1544,7 @@ mod tests {
|
|
|
1434
1544
|
// what would have happened if we woke up with new history -- but it does mean we
|
|
1435
1545
|
// generate the commands at this point. This matters b/c we want to make sure the record
|
|
1436
1546
|
// marker command is sent as soon as cancel happens.
|
|
1437
|
-
if cancel_type == WaitCancellationCompleted {
|
|
1547
|
+
if cancel_type == ActivityCancellationType::WaitCancellationCompleted {
|
|
1438
1548
|
wfm.complete_local_activity(1, ActivityExecutionResult::cancel_from_details(None))
|
|
1439
1549
|
.unwrap();
|
|
1440
1550
|
}
|
|
@@ -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)),
|
|
@@ -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 {
|
|
@@ -270,7 +278,7 @@ trait Cancellable: StateMachine {
|
|
|
270
278
|
}
|
|
271
279
|
}
|
|
272
280
|
|
|
273
|
-
/// We need to wrap calls to [StateMachine::
|
|
281
|
+
/// We need to wrap calls to [StateMachine::on_event] to track coverage, or anything else
|
|
274
282
|
/// we'd like to do on every call.
|
|
275
283
|
pub(crate) trait OnEventWrapper: StateMachine
|
|
276
284
|
where
|
|
@@ -287,7 +295,7 @@ where
|
|
|
287
295
|
#[cfg(test)]
|
|
288
296
|
let converted_event_str = event.to_string();
|
|
289
297
|
|
|
290
|
-
let res = StateMachine::
|
|
298
|
+
let res = StateMachine::on_event(self, event);
|
|
291
299
|
if res.is_ok() {
|
|
292
300
|
#[cfg(test)]
|
|
293
301
|
add_coverage(
|
package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
use super::{workflow_machines::MachineResponse, NewMachineWithCommand};
|
|
2
2
|
use crate::worker::workflow::{
|
|
3
|
-
machines::{Cancellable, EventInfo, WFMachinesAdapter},
|
|
3
|
+
machines::{Cancellable, EventInfo, HistEventData, WFMachinesAdapter},
|
|
4
4
|
WFMachinesError,
|
|
5
5
|
};
|
|
6
|
-
use rustfsm::{fsm, TransitionResult};
|
|
6
|
+
use rustfsm::{fsm, StateMachine, TransitionResult};
|
|
7
7
|
use temporal_sdk_core_protos::{
|
|
8
8
|
coresdk::workflow_commands::ModifyWorkflowProperties,
|
|
9
9
|
temporal::api::{
|
|
@@ -28,10 +28,7 @@ fsm! {
|
|
|
28
28
|
pub(super) fn modify_workflow_properties(
|
|
29
29
|
lang_cmd: ModifyWorkflowProperties,
|
|
30
30
|
) -> NewMachineWithCommand {
|
|
31
|
-
let sm = ModifyWorkflowPropertiesMachine {
|
|
32
|
-
state: Created {}.into(),
|
|
33
|
-
shared_state: (),
|
|
34
|
-
};
|
|
31
|
+
let sm = ModifyWorkflowPropertiesMachine::from_parts(Created {}.into(), ());
|
|
35
32
|
let cmd = Command {
|
|
36
33
|
command_type: CommandType::ModifyWorkflowProperties as i32,
|
|
37
34
|
attributes: Some(lang_cmd.into()),
|
|
@@ -74,10 +71,11 @@ impl WFMachinesAdapter for ModifyWorkflowPropertiesMachine {
|
|
|
74
71
|
|
|
75
72
|
impl Cancellable for ModifyWorkflowPropertiesMachine {}
|
|
76
73
|
|
|
77
|
-
impl TryFrom<
|
|
74
|
+
impl TryFrom<HistEventData> for ModifyWorkflowPropertiesMachineEvents {
|
|
78
75
|
type Error = WFMachinesError;
|
|
79
76
|
|
|
80
|
-
fn try_from(e:
|
|
77
|
+
fn try_from(e: HistEventData) -> Result<Self, Self::Error> {
|
|
78
|
+
let e = e.event;
|
|
81
79
|
match e.event_type() {
|
|
82
80
|
EventType::WorkflowPropertiesModified => {
|
|
83
81
|
Ok(ModifyWorkflowPropertiesMachineEvents::CommandRecorded)
|