@temporalio/core-bridge 1.5.2 → 1.7.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 +304 -112
- package/lib/index.d.ts +8 -6
- package/lib/index.js.map +1 -1
- package/package.json +9 -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/docker/Dockerfile +2 -2
- package/sdk-core/.buildkite/docker/docker-compose.yaml +1 -1
- package/sdk-core/.buildkite/pipeline.yml +2 -4
- package/sdk-core/.cargo/config.toml +5 -2
- package/sdk-core/.github/workflows/heavy.yml +29 -0
- package/sdk-core/Cargo.toml +1 -1
- package/sdk-core/README.md +20 -10
- package/sdk-core/client/src/lib.rs +215 -39
- package/sdk-core/client/src/metrics.rs +17 -8
- package/sdk-core/client/src/raw.rs +4 -4
- package/sdk-core/client/src/retry.rs +32 -20
- package/sdk-core/core/Cargo.toml +25 -12
- package/sdk-core/core/src/abstractions/take_cell.rs +28 -0
- package/sdk-core/core/src/abstractions.rs +204 -14
- package/sdk-core/core/src/core_tests/activity_tasks.rs +143 -50
- package/sdk-core/core/src/core_tests/child_workflows.rs +6 -5
- package/sdk-core/core/src/core_tests/determinism.rs +165 -2
- package/sdk-core/core/src/core_tests/local_activities.rs +431 -43
- package/sdk-core/core/src/core_tests/queries.rs +34 -16
- package/sdk-core/core/src/core_tests/workers.rs +8 -5
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +588 -55
- package/sdk-core/core/src/ephemeral_server/mod.rs +113 -12
- package/sdk-core/core/src/internal_flags.rs +155 -0
- package/sdk-core/core/src/lib.rs +16 -9
- package/sdk-core/core/src/protosext/mod.rs +1 -1
- package/sdk-core/core/src/replay/mod.rs +16 -27
- package/sdk-core/core/src/telemetry/log_export.rs +1 -1
- package/sdk-core/core/src/telemetry/metrics.rs +69 -35
- package/sdk-core/core/src/telemetry/mod.rs +60 -21
- package/sdk-core/core/src/telemetry/prometheus_server.rs +19 -13
- package/sdk-core/core/src/test_help/mod.rs +73 -14
- 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 +379 -129
- package/sdk-core/core/src/worker/activities.rs +350 -175
- 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 +183 -64
- 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 +916 -277
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +216 -183
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +9 -12
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +7 -9
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +160 -87
- package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +13 -14
- package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +7 -9
- package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +14 -17
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +242 -110
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +27 -19
- package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +9 -11
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +321 -206
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +13 -18
- package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +20 -29
- 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 +257 -51
- 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 +310 -150
- package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +17 -20
- package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +31 -15
- package/sdk-core/core/src/worker/workflow/managed_run.rs +1052 -380
- package/sdk-core/core/src/worker/workflow/mod.rs +598 -390
- package/sdk-core/core/src/worker/workflow/run_cache.rs +40 -57
- package/sdk-core/core/src/worker/workflow/wft_extraction.rs +137 -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 +117 -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 +469 -718
- package/sdk-core/core-api/Cargo.toml +2 -1
- package/sdk-core/core-api/src/errors.rs +1 -34
- package/sdk-core/core-api/src/lib.rs +19 -9
- package/sdk-core/core-api/src/telemetry.rs +4 -6
- package/sdk-core/core-api/src/worker.rs +19 -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 +86 -61
- package/sdk-core/fsm/rustfsm_trait/src/lib.rs +29 -71
- package/sdk-core/histories/ends_empty_wft_complete.bin +0 -0
- package/sdk-core/histories/evict_while_la_running_no_interference-16_history.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 +6 -6
- 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 +7 -26
- package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +13 -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 -7
- 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 +8 -8
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +25 -2
- 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 +24 -19
- 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 +49 -26
- package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +4 -2
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +5 -2
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/protocol/v1/message.proto +57 -0
- 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/sdk/v1/task_complete_metadata.proto +63 -0
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +71 -6
- 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 +64 -28
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +4 -4
- 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 +67 -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/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 +5 -4
- package/sdk-core/sdk/src/lib.rs +108 -26
- 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 +16 -15
- 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 +138 -106
- package/sdk-core/sdk-core-protos/src/history_info.rs +10 -1
- package/sdk-core/sdk-core-protos/src/lib.rs +272 -87
- 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/canned_histories.rs +106 -296
- package/sdk-core/test-utils/src/histfetch.rs +1 -1
- package/sdk-core/test-utils/src/lib.rs +82 -23
- 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} +125 -51
- package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +25 -3
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +10 -5
- package/sdk-core/tests/integ_tests/metrics_tests.rs +218 -16
- package/sdk-core/tests/integ_tests/polling_tests.rs +4 -47
- package/sdk-core/tests/integ_tests/queries_tests.rs +5 -128
- package/sdk-core/tests/integ_tests/visibility_tests.rs +83 -25
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +161 -72
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -0
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +6 -13
- 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 +6 -2
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -10
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +94 -200
- package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +2 -4
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +34 -28
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +76 -7
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -0
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +18 -14
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +6 -20
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +10 -21
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +7 -8
- package/sdk-core/tests/integ_tests/workflow_tests.rs +13 -14
- package/sdk-core/tests/main.rs +3 -13
- package/sdk-core/tests/runner.rs +75 -36
- package/sdk-core/tests/wf_input_replay.rs +32 -0
- package/src/conversions.rs +14 -8
- package/src/runtime.rs +9 -8
- package/ts/index.ts +8 -6
- 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
|
@@ -2,7 +2,7 @@ use std::{
|
|
|
2
2
|
sync::atomic::{AtomicUsize, Ordering},
|
|
3
3
|
time::Duration,
|
|
4
4
|
};
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
use temporal_sdk::{ActivityOptions, WfContext, WorkflowResult};
|
|
7
7
|
use temporal_sdk_core_test_utils::CoreWfStarter;
|
|
8
8
|
|
|
@@ -36,18 +36,11 @@ pub async fn timer_wf_nondeterministic(ctx: WfContext) -> WorkflowResult<()> {
|
|
|
36
36
|
async fn test_determinism_error_then_recovers() {
|
|
37
37
|
let wf_name = "test_determinism_error_then_recovers";
|
|
38
38
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
39
|
+
starter.no_remote_activities();
|
|
39
40
|
let mut worker = starter.worker().await;
|
|
40
41
|
|
|
41
42
|
worker.register_wf(wf_name.to_owned(), timer_wf_nondeterministic);
|
|
42
|
-
worker
|
|
43
|
-
.submit_wf(
|
|
44
|
-
wf_name.to_owned(),
|
|
45
|
-
wf_name.to_owned(),
|
|
46
|
-
vec![],
|
|
47
|
-
WorkflowOptions::default(),
|
|
48
|
-
)
|
|
49
|
-
.await
|
|
50
|
-
.unwrap();
|
|
43
|
+
starter.start_with_worker(wf_name, &mut worker).await;
|
|
51
44
|
worker.run_until_done().await.unwrap();
|
|
52
45
|
// 4 because we still add on the 3rd and final attempt
|
|
53
46
|
assert_eq!(RUN_CT.load(Ordering::Relaxed), 4);
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
use anyhow::anyhow;
|
|
2
2
|
use futures::future::join_all;
|
|
3
|
-
use
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
use std::{
|
|
4
|
+
sync::atomic::{AtomicU8, Ordering},
|
|
5
|
+
time::Duration,
|
|
6
|
+
};
|
|
7
|
+
use temporal_client::WorkflowOptions;
|
|
6
8
|
use temporal_sdk::{
|
|
7
|
-
interceptors::WorkerInterceptor, ActContext, ActivityCancelledError,
|
|
8
|
-
|
|
9
|
+
interceptors::WorkerInterceptor, ActContext, ActivityCancelledError, CancellableFuture,
|
|
10
|
+
LocalActivityOptions, WfContext, WorkflowResult,
|
|
9
11
|
};
|
|
10
12
|
use temporal_sdk_core::replay::HistoryForReplay;
|
|
11
13
|
use temporal_sdk_core_protos::{
|
|
12
14
|
coresdk::{
|
|
13
|
-
workflow_commands::ActivityCancellationType,
|
|
15
|
+
workflow_commands::workflow_command::Variant, workflow_commands::ActivityCancellationType,
|
|
16
|
+
workflow_completion, workflow_completion::workflow_activation_completion,
|
|
14
17
|
workflow_completion::WorkflowActivationCompletion, AsJsonPayloadExt,
|
|
15
18
|
},
|
|
16
|
-
temporal::api::common::v1::RetryPolicy,
|
|
19
|
+
temporal::api::{common::v1::RetryPolicy, enums::v1::TimeoutType},
|
|
17
20
|
TestHistoryBuilder,
|
|
18
21
|
};
|
|
19
22
|
use temporal_sdk_core_test_utils::{
|
|
20
|
-
history_from_proto_binary, init_integ_telem, replay_sdk_worker,
|
|
23
|
+
history_from_proto_binary, init_integ_telem, replay_sdk_worker, workflows::la_problem_workflow,
|
|
24
|
+
CoreWfStarter,
|
|
21
25
|
};
|
|
22
26
|
use tokio_util::sync::CancellationToken;
|
|
23
27
|
|
|
@@ -46,15 +50,7 @@ async fn one_local_activity() {
|
|
|
46
50
|
worker.register_wf(wf_name.to_owned(), one_local_activity_wf);
|
|
47
51
|
worker.register_activity("echo_activity", echo);
|
|
48
52
|
|
|
49
|
-
worker
|
|
50
|
-
.submit_wf(
|
|
51
|
-
wf_name.to_owned(),
|
|
52
|
-
wf_name.to_owned(),
|
|
53
|
-
vec![],
|
|
54
|
-
WorkflowOptions::default(),
|
|
55
|
-
)
|
|
56
|
-
.await
|
|
57
|
-
.unwrap();
|
|
53
|
+
starter.start_with_worker(wf_name, &mut worker).await;
|
|
58
54
|
worker.run_until_done().await.unwrap();
|
|
59
55
|
}
|
|
60
56
|
|
|
@@ -77,15 +73,7 @@ async fn local_act_concurrent_with_timer() {
|
|
|
77
73
|
worker.register_wf(wf_name.to_owned(), local_act_concurrent_with_timer_wf);
|
|
78
74
|
worker.register_activity("echo_activity", echo);
|
|
79
75
|
|
|
80
|
-
worker
|
|
81
|
-
.submit_wf(
|
|
82
|
-
wf_name.to_owned(),
|
|
83
|
-
wf_name.to_owned(),
|
|
84
|
-
vec![],
|
|
85
|
-
WorkflowOptions::default(),
|
|
86
|
-
)
|
|
87
|
-
.await
|
|
88
|
-
.unwrap();
|
|
76
|
+
starter.start_with_worker(wf_name, &mut worker).await;
|
|
89
77
|
worker.run_until_done().await.unwrap();
|
|
90
78
|
}
|
|
91
79
|
|
|
@@ -109,15 +97,7 @@ async fn local_act_then_timer_then_wait_result() {
|
|
|
109
97
|
worker.register_wf(wf_name.to_owned(), local_act_then_timer_then_wait);
|
|
110
98
|
worker.register_activity("echo_activity", echo);
|
|
111
99
|
|
|
112
|
-
worker
|
|
113
|
-
.submit_wf(
|
|
114
|
-
wf_name.to_owned(),
|
|
115
|
-
wf_name.to_owned(),
|
|
116
|
-
vec![],
|
|
117
|
-
WorkflowOptions::default(),
|
|
118
|
-
)
|
|
119
|
-
.await
|
|
120
|
-
.unwrap();
|
|
100
|
+
starter.start_with_worker(wf_name, &mut worker).await;
|
|
121
101
|
worker.run_until_done().await.unwrap();
|
|
122
102
|
}
|
|
123
103
|
|
|
@@ -125,7 +105,7 @@ async fn local_act_then_timer_then_wait_result() {
|
|
|
125
105
|
async fn long_running_local_act_with_timer() {
|
|
126
106
|
let wf_name = "long_running_local_act_with_timer";
|
|
127
107
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
128
|
-
starter.
|
|
108
|
+
starter.workflow_options.task_timeout = Some(Duration::from_secs(1));
|
|
129
109
|
let mut worker = starter.worker().await;
|
|
130
110
|
worker.register_wf(wf_name.to_owned(), local_act_then_timer_then_wait);
|
|
131
111
|
worker.register_activity("echo_activity", |_ctx: ActContext, str: String| async {
|
|
@@ -133,15 +113,7 @@ async fn long_running_local_act_with_timer() {
|
|
|
133
113
|
Ok(str)
|
|
134
114
|
});
|
|
135
115
|
|
|
136
|
-
worker
|
|
137
|
-
.submit_wf(
|
|
138
|
-
wf_name.to_owned(),
|
|
139
|
-
wf_name.to_owned(),
|
|
140
|
-
vec![],
|
|
141
|
-
WorkflowOptions::default(),
|
|
142
|
-
)
|
|
143
|
-
.await
|
|
144
|
-
.unwrap();
|
|
116
|
+
starter.start_with_worker(wf_name, &mut worker).await;
|
|
145
117
|
worker.run_until_done().await.unwrap();
|
|
146
118
|
}
|
|
147
119
|
|
|
@@ -150,7 +122,7 @@ pub async fn local_act_fanout_wf(ctx: WfContext) -> WorkflowResult<()> {
|
|
|
150
122
|
.map(|i| {
|
|
151
123
|
ctx.local_activity(LocalActivityOptions {
|
|
152
124
|
activity_type: "echo_activity".to_string(),
|
|
153
|
-
input: format!("Hi {}"
|
|
125
|
+
input: format!("Hi {i}")
|
|
154
126
|
.as_json_payload()
|
|
155
127
|
.expect("serializes fine"),
|
|
156
128
|
..Default::default()
|
|
@@ -171,15 +143,7 @@ async fn local_act_fanout() {
|
|
|
171
143
|
worker.register_wf(wf_name.to_owned(), local_act_fanout_wf);
|
|
172
144
|
worker.register_activity("echo_activity", echo);
|
|
173
145
|
|
|
174
|
-
worker
|
|
175
|
-
.submit_wf(
|
|
176
|
-
wf_name.to_owned(),
|
|
177
|
-
wf_name.to_owned(),
|
|
178
|
-
vec![],
|
|
179
|
-
WorkflowOptions::default(),
|
|
180
|
-
)
|
|
181
|
-
.await
|
|
182
|
-
.unwrap();
|
|
146
|
+
starter.start_with_worker(wf_name, &mut worker).await;
|
|
183
147
|
worker.run_until_done().await.unwrap();
|
|
184
148
|
}
|
|
185
149
|
|
|
@@ -234,7 +198,7 @@ async fn local_act_retry_timer_backoff() {
|
|
|
234
198
|
#[case::abandon(ActivityCancellationType::Abandon)]
|
|
235
199
|
#[tokio::test]
|
|
236
200
|
async fn cancel_immediate(#[case] cancel_type: ActivityCancellationType) {
|
|
237
|
-
let wf_name = format!("cancel_immediate_{:?}"
|
|
201
|
+
let wf_name = format!("cancel_immediate_{cancel_type:?}");
|
|
238
202
|
let mut starter = CoreWfStarter::new(&wf_name);
|
|
239
203
|
let mut worker = starter.worker().await;
|
|
240
204
|
worker.register_wf(&wf_name, move |ctx: WfContext| async move {
|
|
@@ -268,17 +232,10 @@ async fn cancel_immediate(#[case] cancel_type: ActivityCancellationType) {
|
|
|
268
232
|
}
|
|
269
233
|
});
|
|
270
234
|
|
|
271
|
-
worker
|
|
272
|
-
.submit_wf(
|
|
273
|
-
wf_name.to_owned(),
|
|
274
|
-
wf_name.to_owned(),
|
|
275
|
-
vec![],
|
|
276
|
-
WorkflowOptions::default(),
|
|
277
|
-
)
|
|
278
|
-
.await
|
|
279
|
-
.unwrap();
|
|
235
|
+
starter.start_with_worker(wf_name, &mut worker).await;
|
|
280
236
|
worker
|
|
281
237
|
.run_until_done_intercepted(Some(LACancellerInterceptor {
|
|
238
|
+
cancel_on_workflow_completed: false,
|
|
282
239
|
token: manual_cancel,
|
|
283
240
|
}))
|
|
284
241
|
.await
|
|
@@ -287,12 +244,29 @@ async fn cancel_immediate(#[case] cancel_type: ActivityCancellationType) {
|
|
|
287
244
|
|
|
288
245
|
struct LACancellerInterceptor {
|
|
289
246
|
token: CancellationToken,
|
|
247
|
+
cancel_on_workflow_completed: bool,
|
|
290
248
|
}
|
|
291
249
|
#[async_trait::async_trait(?Send)]
|
|
292
250
|
impl WorkerInterceptor for LACancellerInterceptor {
|
|
293
|
-
async fn on_workflow_activation_completion(&self,
|
|
251
|
+
async fn on_workflow_activation_completion(&self, completion: &WorkflowActivationCompletion) {
|
|
252
|
+
if !self.cancel_on_workflow_completed {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if let Some(workflow_activation_completion::Status::Successful(
|
|
256
|
+
workflow_completion::Success { commands, .. },
|
|
257
|
+
)) = completion.status.as_ref()
|
|
258
|
+
{
|
|
259
|
+
if let Some(&Variant::CompleteWorkflowExecution(_)) =
|
|
260
|
+
commands.last().and_then(|v| v.variant.as_ref())
|
|
261
|
+
{
|
|
262
|
+
self.token.cancel();
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
294
266
|
fn on_shutdown(&self, _: &temporal_sdk::Worker) {
|
|
295
|
-
self.
|
|
267
|
+
if !self.cancel_on_workflow_completed {
|
|
268
|
+
self.token.cancel()
|
|
269
|
+
}
|
|
296
270
|
}
|
|
297
271
|
}
|
|
298
272
|
|
|
@@ -310,12 +284,9 @@ async fn cancel_after_act_starts(
|
|
|
310
284
|
)]
|
|
311
285
|
cancel_type: ActivityCancellationType,
|
|
312
286
|
) {
|
|
313
|
-
let wf_name = format!(
|
|
314
|
-
"cancel_after_act_starts_timer_{:?}_{:?}",
|
|
315
|
-
cancel_on_backoff, cancel_type
|
|
316
|
-
);
|
|
287
|
+
let wf_name = format!("cancel_after_act_starts_{cancel_on_backoff:?}_{cancel_type:?}");
|
|
317
288
|
let mut starter = CoreWfStarter::new(&wf_name);
|
|
318
|
-
starter.
|
|
289
|
+
starter.workflow_options.task_timeout = Some(Duration::from_secs(1));
|
|
319
290
|
let mut worker = starter.worker().await;
|
|
320
291
|
let bo_dur = cancel_on_backoff.unwrap_or_else(|| Duration::from_secs(1));
|
|
321
292
|
worker.register_wf(&wf_name, move |ctx: WfContext| async move {
|
|
@@ -375,21 +346,17 @@ async fn cancel_after_act_starts(
|
|
|
375
346
|
}
|
|
376
347
|
});
|
|
377
348
|
|
|
378
|
-
worker
|
|
379
|
-
.submit_wf(
|
|
380
|
-
wf_name.to_owned(),
|
|
381
|
-
wf_name.to_owned(),
|
|
382
|
-
vec![],
|
|
383
|
-
WorkflowOptions::default(),
|
|
384
|
-
)
|
|
385
|
-
.await
|
|
386
|
-
.unwrap();
|
|
349
|
+
starter.start_with_worker(&wf_name, &mut worker).await;
|
|
387
350
|
worker
|
|
388
351
|
.run_until_done_intercepted(Some(LACancellerInterceptor {
|
|
389
352
|
token: manual_cancel,
|
|
353
|
+
// Only needed for this one case since the activity is not drained and prevents worker from shutting down.
|
|
354
|
+
cancel_on_workflow_completed: matches!(cancel_type, ActivityCancellationType::Abandon)
|
|
355
|
+
&& cancel_on_backoff.is_none(),
|
|
390
356
|
}))
|
|
391
357
|
.await
|
|
392
358
|
.unwrap();
|
|
359
|
+
starter.shutdown().await;
|
|
393
360
|
}
|
|
394
361
|
|
|
395
362
|
#[rstest::rstest]
|
|
@@ -408,6 +375,11 @@ async fn x_to_close_timeout(#[case] is_schedule: bool) {
|
|
|
408
375
|
} else {
|
|
409
376
|
(None, Some(Duration::from_secs(2)))
|
|
410
377
|
};
|
|
378
|
+
let timeout_type = if is_schedule {
|
|
379
|
+
TimeoutType::ScheduleToClose
|
|
380
|
+
} else {
|
|
381
|
+
TimeoutType::StartToClose
|
|
382
|
+
};
|
|
411
383
|
|
|
412
384
|
worker.register_wf(wf_name.to_owned(), move |ctx: WfContext| async move {
|
|
413
385
|
let res = ctx
|
|
@@ -427,7 +399,7 @@ async fn x_to_close_timeout(#[case] is_schedule: bool) {
|
|
|
427
399
|
..Default::default()
|
|
428
400
|
})
|
|
429
401
|
.await;
|
|
430
|
-
|
|
402
|
+
assert_eq!(res.timed_out(), Some(timeout_type));
|
|
431
403
|
Ok(().into())
|
|
432
404
|
});
|
|
433
405
|
worker.register_activity("echo", |ctx: ActContext, _: String| async move {
|
|
@@ -440,15 +412,7 @@ async fn x_to_close_timeout(#[case] is_schedule: bool) {
|
|
|
440
412
|
Ok(())
|
|
441
413
|
});
|
|
442
414
|
|
|
443
|
-
worker
|
|
444
|
-
.submit_wf(
|
|
445
|
-
wf_name.to_owned(),
|
|
446
|
-
wf_name.to_owned(),
|
|
447
|
-
vec![],
|
|
448
|
-
WorkflowOptions::default(),
|
|
449
|
-
)
|
|
450
|
-
.await
|
|
451
|
-
.unwrap();
|
|
415
|
+
starter.start_with_worker(wf_name, &mut worker).await;
|
|
452
416
|
worker.run_until_done().await.unwrap();
|
|
453
417
|
}
|
|
454
418
|
|
|
@@ -472,43 +436,37 @@ async fn schedule_to_close_timeout_across_timer_backoff(#[case] cached: bool) {
|
|
|
472
436
|
activity_type: "echo".to_string(),
|
|
473
437
|
input: "hi".as_json_payload().expect("serializes fine"),
|
|
474
438
|
retry_policy: RetryPolicy {
|
|
475
|
-
initial_interval: Some(prost_dur!(
|
|
439
|
+
initial_interval: Some(prost_dur!(from_millis(15))),
|
|
476
440
|
backoff_coefficient: 1_000.,
|
|
477
|
-
maximum_interval: Some(prost_dur!(from_millis(
|
|
441
|
+
maximum_interval: Some(prost_dur!(from_millis(1000))),
|
|
478
442
|
maximum_attempts: 40,
|
|
479
443
|
non_retryable_error_types: vec![],
|
|
480
444
|
},
|
|
481
|
-
timer_backoff_threshold: Some(Duration::
|
|
482
|
-
schedule_to_close_timeout: Some(Duration::from_secs(
|
|
445
|
+
timer_backoff_threshold: Some(Duration::from_millis(500)),
|
|
446
|
+
schedule_to_close_timeout: Some(Duration::from_secs(2)),
|
|
483
447
|
..Default::default()
|
|
484
448
|
})
|
|
485
449
|
.await;
|
|
486
|
-
|
|
450
|
+
assert_eq!(res.timed_out(), Some(TimeoutType::ScheduleToClose));
|
|
487
451
|
Ok(().into())
|
|
488
452
|
});
|
|
489
|
-
|
|
453
|
+
let num_attempts: &'static _ = Box::leak(Box::new(AtomicU8::new(0)));
|
|
454
|
+
worker.register_activity("echo", move |_: ActContext, _: String| async {
|
|
455
|
+
num_attempts.fetch_add(1, Ordering::Relaxed);
|
|
490
456
|
Result::<(), _>::Err(anyhow!("Oh no I failed!"))
|
|
491
457
|
});
|
|
492
458
|
|
|
493
|
-
worker
|
|
494
|
-
.submit_wf(
|
|
495
|
-
wf_name.to_owned(),
|
|
496
|
-
wf_name.to_owned(),
|
|
497
|
-
vec![],
|
|
498
|
-
WorkflowOptions::default(),
|
|
499
|
-
)
|
|
500
|
-
.await
|
|
501
|
-
.unwrap();
|
|
459
|
+
starter.start_with_worker(wf_name, &mut worker).await;
|
|
502
460
|
worker.run_until_done().await.unwrap();
|
|
461
|
+
// 3 attempts b/c first backoff is very small, then the next 2 attempts take at least 2 seconds
|
|
462
|
+
// b/c of timer backoff.
|
|
463
|
+
assert_eq!(3, num_attempts.load(Ordering::Relaxed));
|
|
503
464
|
}
|
|
504
465
|
|
|
505
466
|
#[rstest::rstest]
|
|
506
467
|
#[tokio::test]
|
|
507
468
|
async fn eviction_wont_make_local_act_get_dropped(#[values(true, false)] short_wft_timeout: bool) {
|
|
508
|
-
let wf_name = format!(
|
|
509
|
-
"eviction_wont_make_local_act_get_dropped_{}",
|
|
510
|
-
short_wft_timeout
|
|
511
|
-
);
|
|
469
|
+
let wf_name = format!("eviction_wont_make_local_act_get_dropped_{short_wft_timeout}");
|
|
512
470
|
let mut starter = CoreWfStarter::new(&wf_name);
|
|
513
471
|
starter.max_cached_workflows(0);
|
|
514
472
|
let mut worker = starter.worker().await;
|
|
@@ -574,15 +532,7 @@ async fn timer_backoff_concurrent_with_non_timer_backoff() {
|
|
|
574
532
|
Result::<(), _>::Err(anyhow!("Oh no I failed!"))
|
|
575
533
|
});
|
|
576
534
|
|
|
577
|
-
worker
|
|
578
|
-
.submit_wf(
|
|
579
|
-
wf_name.to_owned(),
|
|
580
|
-
wf_name.to_owned(),
|
|
581
|
-
vec![],
|
|
582
|
-
WorkflowOptions::default(),
|
|
583
|
-
)
|
|
584
|
-
.await
|
|
585
|
-
.unwrap();
|
|
535
|
+
starter.start_with_worker(wf_name, &mut worker).await;
|
|
586
536
|
worker.run_until_done().await.unwrap();
|
|
587
537
|
}
|
|
588
538
|
|
|
@@ -613,7 +563,7 @@ async fn repro_nondeterminism_with_timer_bug() {
|
|
|
613
563
|
_ = r1 => {
|
|
614
564
|
t1.cancel(&ctx);
|
|
615
565
|
},
|
|
616
|
-
}
|
|
566
|
+
}
|
|
617
567
|
ctx.timer(Duration::from_secs(1)).await;
|
|
618
568
|
Ok(().into())
|
|
619
569
|
});
|
|
@@ -638,85 +588,6 @@ async fn repro_nondeterminism_with_timer_bug() {
|
|
|
638
588
|
.unwrap();
|
|
639
589
|
}
|
|
640
590
|
|
|
641
|
-
async fn la_problem_workflow(ctx: WfContext) -> WorkflowResult<()> {
|
|
642
|
-
ctx.local_activity(LocalActivityOptions {
|
|
643
|
-
activity_type: "delay".to_string(),
|
|
644
|
-
input: "hi".as_json_payload().expect("serializes fine"),
|
|
645
|
-
retry_policy: RetryPolicy {
|
|
646
|
-
initial_interval: Some(prost_dur!(from_micros(15))),
|
|
647
|
-
backoff_coefficient: 1_000.,
|
|
648
|
-
maximum_interval: Some(prost_dur!(from_millis(1500))),
|
|
649
|
-
maximum_attempts: 4,
|
|
650
|
-
non_retryable_error_types: vec![],
|
|
651
|
-
},
|
|
652
|
-
timer_backoff_threshold: Some(Duration::from_secs(1)),
|
|
653
|
-
..Default::default()
|
|
654
|
-
})
|
|
655
|
-
.await;
|
|
656
|
-
ctx.activity(ActivityOptions {
|
|
657
|
-
activity_type: "delay".to_string(),
|
|
658
|
-
start_to_close_timeout: Some(Duration::from_secs(20)),
|
|
659
|
-
input: "hi!".as_json_payload().expect("serializes fine"),
|
|
660
|
-
..Default::default()
|
|
661
|
-
})
|
|
662
|
-
.await;
|
|
663
|
-
Ok(().into())
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
// Expensive to run - worth enabling on a stress/regression pipeline.
|
|
667
|
-
#[ignore]
|
|
668
|
-
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
|
|
669
|
-
async fn evict_while_la_running_no_interference() {
|
|
670
|
-
let wf_name = "evict_while_la_running_no_interference";
|
|
671
|
-
let mut starter = CoreWfStarter::new(wf_name);
|
|
672
|
-
starter.max_local_at(20);
|
|
673
|
-
starter.max_cached_workflows(20);
|
|
674
|
-
let mut worker = starter.worker().await;
|
|
675
|
-
|
|
676
|
-
worker.register_wf(wf_name.to_owned(), la_problem_workflow);
|
|
677
|
-
worker.register_activity("delay", |_: ActContext, _: String| async {
|
|
678
|
-
tokio::time::sleep(Duration::from_secs(15)).await;
|
|
679
|
-
Ok(())
|
|
680
|
-
});
|
|
681
|
-
|
|
682
|
-
let client = starter.get_client().await;
|
|
683
|
-
let subfs = FuturesUnordered::new();
|
|
684
|
-
for i in 1..100 {
|
|
685
|
-
let wf_id = format!("{}-{}", wf_name, i);
|
|
686
|
-
let run_id = worker
|
|
687
|
-
.submit_wf(
|
|
688
|
-
&wf_id,
|
|
689
|
-
wf_name.to_owned(),
|
|
690
|
-
vec![],
|
|
691
|
-
WorkflowOptions::default(),
|
|
692
|
-
)
|
|
693
|
-
.await
|
|
694
|
-
.unwrap();
|
|
695
|
-
let cw = worker.core_worker.clone();
|
|
696
|
-
let client = client.clone();
|
|
697
|
-
subfs.push(async move {
|
|
698
|
-
// Evict the workflow
|
|
699
|
-
tokio::time::sleep(Duration::from_secs(1)).await;
|
|
700
|
-
cw.request_workflow_eviction(&run_id);
|
|
701
|
-
// Wake up workflow by sending signal
|
|
702
|
-
client
|
|
703
|
-
.signal_workflow_execution(
|
|
704
|
-
wf_id,
|
|
705
|
-
run_id.clone(),
|
|
706
|
-
"whaatever".to_string(),
|
|
707
|
-
None,
|
|
708
|
-
None,
|
|
709
|
-
)
|
|
710
|
-
.await
|
|
711
|
-
.unwrap();
|
|
712
|
-
});
|
|
713
|
-
}
|
|
714
|
-
let runf = async {
|
|
715
|
-
worker.run_until_done().await.unwrap();
|
|
716
|
-
};
|
|
717
|
-
tokio::join!(subfs.collect::<Vec<_>>(), runf);
|
|
718
|
-
}
|
|
719
|
-
|
|
720
591
|
#[rstest::rstest]
|
|
721
592
|
#[tokio::test]
|
|
722
593
|
async fn weird_la_nondeterminism_repro(#[values(true, false)] fix_hist: bool) {
|
|
@@ -758,7 +629,6 @@ async fn second_weird_la_nondeterminism_repro() {
|
|
|
758
629
|
// Chop off uninteresting ending
|
|
759
630
|
hist.events.truncate(24);
|
|
760
631
|
let mut thb = TestHistoryBuilder::from_history(hist.events);
|
|
761
|
-
// thb.add_workflow_task_completed();
|
|
762
632
|
thb.add_workflow_execution_completed();
|
|
763
633
|
hist = thb.get_full_history_info().unwrap().into();
|
|
764
634
|
|
|
@@ -773,3 +643,27 @@ async fn second_weird_la_nondeterminism_repro() {
|
|
|
773
643
|
});
|
|
774
644
|
worker.run().await.unwrap();
|
|
775
645
|
}
|
|
646
|
+
|
|
647
|
+
#[tokio::test]
|
|
648
|
+
async fn third_weird_la_nondeterminism_repro() {
|
|
649
|
+
init_integ_telem();
|
|
650
|
+
let mut hist = history_from_proto_binary(
|
|
651
|
+
"histories/evict_while_la_running_no_interference-16_history.bin",
|
|
652
|
+
)
|
|
653
|
+
.await
|
|
654
|
+
.unwrap();
|
|
655
|
+
let mut thb = TestHistoryBuilder::from_history(hist.events);
|
|
656
|
+
thb.add_workflow_task_scheduled_and_started();
|
|
657
|
+
hist = thb.get_full_history_info().unwrap().into();
|
|
658
|
+
|
|
659
|
+
let mut worker = replay_sdk_worker([HistoryForReplay::new(hist, "fake".to_owned())]);
|
|
660
|
+
worker.register_wf(
|
|
661
|
+
"evict_while_la_running_no_interference",
|
|
662
|
+
la_problem_workflow,
|
|
663
|
+
);
|
|
664
|
+
worker.register_activity("delay", |_: ActContext, _: String| async {
|
|
665
|
+
tokio::time::sleep(Duration::from_secs(15)).await;
|
|
666
|
+
Ok(())
|
|
667
|
+
});
|
|
668
|
+
worker.run().await.unwrap();
|
|
669
|
+
}
|
|
@@ -20,6 +20,7 @@ async fn sends_modify_wf_props() {
|
|
|
20
20
|
let wf_name = "can_upsert_memo";
|
|
21
21
|
let wf_id = Uuid::new_v4();
|
|
22
22
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
23
|
+
starter.no_remote_activities();
|
|
23
24
|
let mut worker = starter.worker().await;
|
|
24
25
|
|
|
25
26
|
worker.register_wf(wf_name, memo_upserter);
|
|
@@ -43,10 +44,7 @@ async fn sends_modify_wf_props() {
|
|
|
43
44
|
let catname = memo.get(FIELD_A).unwrap();
|
|
44
45
|
let cuteness = memo.get(FIELD_B).unwrap();
|
|
45
46
|
for payload in [catname, cuteness] {
|
|
46
|
-
|
|
47
|
-
&b"json/plain".to_vec(),
|
|
48
|
-
payload.metadata.get("encoding").unwrap()
|
|
49
|
-
);
|
|
47
|
+
assert!(payload.is_json_payload());
|
|
50
48
|
}
|
|
51
49
|
assert_eq!("enchi", String::from_json_payload(catname).unwrap());
|
|
52
50
|
assert_eq!(9001, usize::from_json_payload(cuteness).unwrap());
|
|
@@ -2,7 +2,7 @@ use std::{
|
|
|
2
2
|
sync::atomic::{AtomicBool, Ordering},
|
|
3
3
|
time::Duration,
|
|
4
4
|
};
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
use temporal_sdk::{WfContext, WorkflowResult};
|
|
7
7
|
use temporal_sdk_core_test_utils::CoreWfStarter;
|
|
8
8
|
|
|
@@ -27,18 +27,11 @@ pub async fn changes_wf(ctx: WfContext) -> WorkflowResult<()> {
|
|
|
27
27
|
async fn writes_change_markers() {
|
|
28
28
|
let wf_name = "writes_change_markers";
|
|
29
29
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
30
|
+
starter.no_remote_activities();
|
|
30
31
|
let mut worker = starter.worker().await;
|
|
31
32
|
worker.register_wf(wf_name.to_owned(), changes_wf);
|
|
32
33
|
|
|
33
|
-
worker
|
|
34
|
-
.submit_wf(
|
|
35
|
-
wf_name.to_owned(),
|
|
36
|
-
wf_name.to_owned(),
|
|
37
|
-
vec![],
|
|
38
|
-
WorkflowOptions::default(),
|
|
39
|
-
)
|
|
40
|
-
.await
|
|
41
|
-
.unwrap();
|
|
34
|
+
starter.start_with_worker(wf_name, &mut worker).await;
|
|
42
35
|
worker.run_until_done().await.unwrap();
|
|
43
36
|
}
|
|
44
37
|
|
|
@@ -67,18 +60,11 @@ pub async fn no_change_then_change_wf(ctx: WfContext) -> WorkflowResult<()> {
|
|
|
67
60
|
async fn can_add_change_markers() {
|
|
68
61
|
let wf_name = "can_add_change_markers";
|
|
69
62
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
63
|
+
starter.no_remote_activities();
|
|
70
64
|
let mut worker = starter.worker().await;
|
|
71
65
|
worker.register_wf(wf_name.to_owned(), no_change_then_change_wf);
|
|
72
66
|
|
|
73
|
-
worker
|
|
74
|
-
.submit_wf(
|
|
75
|
-
wf_name.to_owned(),
|
|
76
|
-
wf_name.to_owned(),
|
|
77
|
-
vec![],
|
|
78
|
-
WorkflowOptions::default(),
|
|
79
|
-
)
|
|
80
|
-
.await
|
|
81
|
-
.unwrap();
|
|
67
|
+
starter.start_with_worker(wf_name, &mut worker).await;
|
|
82
68
|
worker.run_until_done().await.unwrap();
|
|
83
69
|
}
|
|
84
70
|
|
|
@@ -97,17 +83,37 @@ pub async fn replay_with_change_marker_wf(ctx: WfContext) -> WorkflowResult<()>
|
|
|
97
83
|
async fn replaying_with_patch_marker() {
|
|
98
84
|
let wf_name = "replaying_with_patch_marker";
|
|
99
85
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
86
|
+
starter.no_remote_activities();
|
|
100
87
|
let mut worker = starter.worker().await;
|
|
101
88
|
worker.register_wf(wf_name.to_owned(), replay_with_change_marker_wf);
|
|
102
89
|
|
|
103
|
-
worker
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
90
|
+
starter.start_with_worker(wf_name, &mut worker).await;
|
|
91
|
+
worker.run_until_done().await.unwrap();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/// Test that the internal patching mechanism works on the second workflow task when replaying.
|
|
95
|
+
/// Used as regression test for a bug that detected that we did not look ahead far enough to find
|
|
96
|
+
/// the next workflow task completion, which the flags are attached to.
|
|
97
|
+
#[tokio::test]
|
|
98
|
+
async fn patched_on_second_workflow_task_is_deterministic() {
|
|
99
|
+
let wf_name = "timer_patched_timer";
|
|
100
|
+
let mut starter = CoreWfStarter::new(wf_name);
|
|
101
|
+
// Disable caching to force replay from beginning
|
|
102
|
+
starter.max_cached_workflows(0).no_remote_activities();
|
|
103
|
+
let mut worker = starter.worker().await;
|
|
104
|
+
// Include a task failure as well to make sure that works
|
|
105
|
+
static FAIL_ONCE: AtomicBool = AtomicBool::new(true);
|
|
106
|
+
worker.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
|
|
107
|
+
ctx.timer(Duration::from_millis(1)).await;
|
|
108
|
+
if FAIL_ONCE.load(Ordering::Acquire) {
|
|
109
|
+
FAIL_ONCE.store(false, Ordering::Release);
|
|
110
|
+
panic!("Enchi is hungry!");
|
|
111
|
+
}
|
|
112
|
+
assert!(ctx.patched(MY_PATCH_ID));
|
|
113
|
+
ctx.timer(Duration::from_millis(1)).await;
|
|
114
|
+
Ok(().into())
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
starter.start_with_worker(wf_name, &mut worker).await;
|
|
112
118
|
worker.run_until_done().await.unwrap();
|
|
113
119
|
}
|