@temporalio/core-bridge 0.16.4 → 0.18.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 +339 -226
- package/Cargo.toml +7 -3
- package/common.js +50 -0
- package/index.d.ts +7 -0
- package/index.js +12 -0
- package/package.json +7 -4
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/{index.node → releases/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/scripts/build.js +10 -50
- package/sdk-core/.buildkite/docker/Dockerfile +1 -1
- package/sdk-core/.buildkite/docker/docker-compose.yaml +2 -2
- package/sdk-core/.buildkite/pipeline.yml +2 -0
- package/sdk-core/Cargo.toml +1 -88
- package/sdk-core/README.md +30 -6
- package/sdk-core/bridge-ffi/Cargo.toml +24 -0
- package/sdk-core/bridge-ffi/LICENSE.txt +23 -0
- package/sdk-core/bridge-ffi/build.rs +25 -0
- package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +216 -0
- package/sdk-core/bridge-ffi/src/lib.rs +829 -0
- package/sdk-core/bridge-ffi/src/wrappers.rs +193 -0
- package/sdk-core/client/Cargo.toml +32 -0
- package/sdk-core/{src/pollers/gateway.rs → client/src/lib.rs} +101 -195
- package/sdk-core/client/src/metrics.rs +89 -0
- package/sdk-core/client/src/mocks.rs +167 -0
- package/sdk-core/{src/pollers → client/src}/retry.rs +172 -14
- package/sdk-core/core/Cargo.toml +96 -0
- package/sdk-core/{src → core/src}/core_tests/activity_tasks.rs +193 -37
- package/sdk-core/{src → core/src}/core_tests/child_workflows.rs +14 -14
- package/sdk-core/{src → core/src}/core_tests/determinism.rs +8 -8
- package/sdk-core/core/src/core_tests/local_activities.rs +328 -0
- package/sdk-core/{src → core/src}/core_tests/mod.rs +6 -9
- package/sdk-core/{src → core/src}/core_tests/queries.rs +54 -54
- package/sdk-core/{src → core/src}/core_tests/replay_flag.rs +8 -12
- package/sdk-core/{src → core/src}/core_tests/workers.rs +120 -33
- package/sdk-core/{src → core/src}/core_tests/workflow_cancels.rs +16 -26
- package/sdk-core/{src → core/src}/core_tests/workflow_tasks.rs +280 -292
- package/sdk-core/core/src/lib.rs +374 -0
- package/sdk-core/{src → core/src}/log_export.rs +3 -27
- package/sdk-core/core/src/pending_activations.rs +162 -0
- package/sdk-core/{src → core/src}/pollers/mod.rs +4 -22
- package/sdk-core/{src → core/src}/pollers/poll_buffer.rs +1 -1
- package/sdk-core/core/src/protosext/mod.rs +396 -0
- package/sdk-core/core/src/replay/mod.rs +210 -0
- package/sdk-core/core/src/retry_logic.rs +144 -0
- package/sdk-core/{src → core/src}/telemetry/metrics.rs +3 -58
- package/sdk-core/{src → core/src}/telemetry/mod.rs +8 -8
- package/sdk-core/{src → core/src}/telemetry/prometheus_server.rs +0 -0
- package/sdk-core/{src → core/src}/test_help/mod.rs +35 -83
- package/sdk-core/{src → core/src}/worker/activities/activity_heartbeat_manager.rs +95 -42
- package/sdk-core/core/src/worker/activities/local_activities.rs +973 -0
- package/sdk-core/{src → core/src}/worker/activities.rs +52 -33
- package/sdk-core/{src → core/src}/worker/dispatcher.rs +8 -6
- package/sdk-core/{src → core/src}/worker/mod.rs +347 -221
- package/sdk-core/core/src/worker/wft_delivery.rs +81 -0
- package/sdk-core/{src → core/src}/workflow/bridge.rs +5 -2
- package/sdk-core/{src → core/src}/workflow/driven_workflow.rs +17 -7
- package/sdk-core/{src → core/src}/workflow/history_update.rs +33 -7
- package/sdk-core/{src → core/src/workflow}/machines/activity_state_machine.rs +26 -26
- package/sdk-core/{src → core/src/workflow}/machines/cancel_external_state_machine.rs +8 -11
- package/sdk-core/{src → core/src/workflow}/machines/cancel_workflow_state_machine.rs +19 -21
- package/sdk-core/{src → core/src/workflow}/machines/child_workflow_state_machine.rs +20 -31
- package/sdk-core/{src → core/src/workflow}/machines/complete_workflow_state_machine.rs +3 -5
- package/sdk-core/{src → core/src/workflow}/machines/continue_as_new_workflow_state_machine.rs +18 -18
- package/sdk-core/{src → core/src/workflow}/machines/fail_workflow_state_machine.rs +5 -6
- package/sdk-core/core/src/workflow/machines/local_activity_state_machine.rs +1451 -0
- package/sdk-core/{src → core/src/workflow}/machines/mod.rs +54 -107
- package/sdk-core/{src → core/src/workflow}/machines/mutable_side_effect_state_machine.rs +0 -0
- package/sdk-core/{src → core/src/workflow}/machines/patch_state_machine.rs +29 -30
- package/sdk-core/{src → core/src/workflow}/machines/side_effect_state_machine.rs +0 -0
- package/sdk-core/{src → core/src/workflow}/machines/signal_external_state_machine.rs +17 -19
- package/sdk-core/{src → core/src/workflow}/machines/timer_state_machine.rs +20 -21
- package/sdk-core/{src → core/src/workflow}/machines/transition_coverage.rs +5 -2
- package/sdk-core/{src → core/src/workflow}/machines/upsert_search_attributes_state_machine.rs +0 -0
- package/sdk-core/core/src/workflow/machines/workflow_machines/local_acts.rs +96 -0
- package/sdk-core/{src → core/src/workflow}/machines/workflow_machines.rs +357 -171
- package/sdk-core/{src → core/src/workflow}/machines/workflow_task_state_machine.rs +1 -1
- package/sdk-core/{src → core/src}/workflow/mod.rs +200 -39
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/cache_manager.rs +0 -0
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/concurrency_manager.rs +38 -5
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/mod.rs +317 -103
- package/sdk-core/{test_utils → core-api}/Cargo.toml +10 -7
- package/sdk-core/{src → core-api/src}/errors.rs +42 -92
- package/sdk-core/core-api/src/lib.rs +158 -0
- package/sdk-core/{src/worker/config.rs → core-api/src/worker.rs} +18 -23
- package/sdk-core/etc/deps.svg +156 -0
- package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +5 -5
- package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +3 -5
- package/sdk-core/fsm/rustfsm_trait/src/lib.rs +7 -1
- package/sdk-core/histories/fail_wf_task.bin +0 -0
- package/sdk-core/histories/timer_workflow_history.bin +0 -0
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +44 -13
- package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +19 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +1 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +9 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +13 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +14 -7
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +176 -18
- package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
- package/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +11 -0
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +3 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +156 -7
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +135 -104
- package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +78 -0
- package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +78 -0
- package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +205 -0
- package/sdk-core/protos/local/temporal/sdk/core/bridge/service.proto +61 -0
- package/sdk-core/protos/local/{child_workflow.proto → temporal/sdk/core/child_workflow/child_workflow.proto} +1 -1
- package/sdk-core/protos/local/{common.proto → temporal/sdk/core/common/common.proto} +5 -3
- package/sdk-core/protos/local/{core_interface.proto → temporal/sdk/core/core_interface.proto} +10 -10
- package/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +30 -0
- package/sdk-core/protos/local/{workflow_activation.proto → temporal/sdk/core/workflow_activation/workflow_activation.proto} +35 -11
- package/sdk-core/protos/local/{workflow_commands.proto → temporal/sdk/core/workflow_commands/workflow_commands.proto} +55 -4
- package/sdk-core/protos/local/{workflow_completion.proto → temporal/sdk/core/workflow_completion/workflow_completion.proto} +3 -3
- package/sdk-core/sdk/Cargo.toml +32 -0
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/conversions.rs +0 -0
- package/sdk-core/sdk/src/lib.rs +699 -0
- package/sdk-core/sdk/src/payload_converter.rs +11 -0
- package/sdk-core/sdk/src/workflow_context/options.rs +180 -0
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_context.rs +201 -124
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_future.rs +63 -30
- package/sdk-core/sdk-core-protos/Cargo.toml +10 -0
- package/sdk-core/sdk-core-protos/build.rs +28 -6
- package/sdk-core/sdk-core-protos/src/constants.rs +7 -0
- package/sdk-core/{src/test_help → sdk-core-protos/src}/history_builder.rs +134 -49
- package/sdk-core/sdk-core-protos/src/history_info.rs +216 -0
- package/sdk-core/sdk-core-protos/src/lib.rs +601 -168
- package/sdk-core/sdk-core-protos/src/task_token.rs +38 -0
- package/sdk-core/sdk-core-protos/src/utilities.rs +14 -0
- package/sdk-core/test-utils/Cargo.toml +32 -0
- package/sdk-core/{src/test_help → test-utils/src}/canned_histories.rs +59 -78
- package/sdk-core/test-utils/src/histfetch.rs +28 -0
- package/sdk-core/{test_utils → test-utils}/src/lib.rs +131 -68
- package/sdk-core/tests/integ_tests/client_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +11 -7
- package/sdk-core/tests/integ_tests/polling_tests.rs +12 -11
- package/sdk-core/tests/integ_tests/queries_tests.rs +82 -78
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +91 -71
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +3 -4
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +2 -4
- package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +4 -6
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +4 -6
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -4
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +496 -0
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +5 -8
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +125 -0
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +7 -13
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +33 -5
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +12 -16
- package/sdk-core/tests/integ_tests/workflow_tests.rs +85 -82
- package/sdk-core/tests/load_tests.rs +6 -6
- package/sdk-core/tests/main.rs +2 -2
- package/src/conversions.rs +24 -21
- package/src/errors.rs +8 -0
- package/src/lib.rs +323 -211
- package/sdk-core/protos/local/activity_result.proto +0 -46
- package/sdk-core/protos/local/activity_task.proto +0 -66
- package/sdk-core/src/core_tests/retry.rs +0 -147
- package/sdk-core/src/lib.rs +0 -403
- package/sdk-core/src/machines/local_activity_state_machine.rs +0 -117
- package/sdk-core/src/pending_activations.rs +0 -249
- package/sdk-core/src/protosext/mod.rs +0 -160
- package/sdk-core/src/prototype_rust_sdk.rs +0 -412
- package/sdk-core/src/task_token.rs +0 -20
- package/sdk-core/src/test_help/history_info.rs +0 -157
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
use crate::{
|
|
2
2
|
errors::PollWfError,
|
|
3
3
|
job_assert,
|
|
4
|
-
|
|
4
|
+
replay::TestHistoryBuilder,
|
|
5
5
|
test_help::{
|
|
6
6
|
build_fake_core, build_mock_pollers, build_multihist_mock_sg, canned_histories,
|
|
7
7
|
gen_assert_and_fail, gen_assert_and_reply, hist_to_poll_resp, mock_core, poll_and_reply,
|
|
8
8
|
poll_and_reply_clears_outstanding_evicts, single_hist_mock_sg, FakeWfResponses,
|
|
9
|
-
MockPollCfg, MocksHolder, ResponseType,
|
|
9
|
+
MockPollCfg, MocksHolder, ResponseType, NO_MORE_WORK_ERROR_MSG, TEST_Q,
|
|
10
10
|
},
|
|
11
11
|
workflow::WorkflowCachingPolicy::{self, AfterEveryReply, NonSticky},
|
|
12
|
-
Core, CoreSDK,
|
|
12
|
+
Core, CoreSDK, WorkflowActivationCompletion,
|
|
13
13
|
};
|
|
14
14
|
use rstest::{fixture, rstest};
|
|
15
15
|
use std::{
|
|
@@ -17,16 +17,17 @@ use std::{
|
|
|
17
17
|
sync::atomic::{AtomicU64, AtomicUsize, Ordering},
|
|
18
18
|
time::Duration,
|
|
19
19
|
};
|
|
20
|
+
use temporal_client::mocks::mock_gateway;
|
|
20
21
|
use temporal_sdk_core_protos::{
|
|
21
22
|
coresdk::{
|
|
22
|
-
activity_result::{self as ar,
|
|
23
|
+
activity_result::{self as ar, activity_resolution, ActivityResolution},
|
|
23
24
|
workflow_activation::{
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
workflow_activation_job, FireTimer, ResolveActivity, StartWorkflow, UpdateRandomSeed,
|
|
26
|
+
WorkflowActivationJob,
|
|
26
27
|
},
|
|
27
28
|
workflow_commands::{
|
|
28
29
|
ActivityCancellationType, CancelTimer, CompleteWorkflowExecution,
|
|
29
|
-
FailWorkflowExecution, RequestCancelActivity, ScheduleActivity,
|
|
30
|
+
FailWorkflowExecution, RequestCancelActivity, ScheduleActivity,
|
|
30
31
|
},
|
|
31
32
|
},
|
|
32
33
|
temporal::api::{
|
|
@@ -36,7 +37,7 @@ use temporal_sdk_core_protos::{
|
|
|
36
37
|
workflowservice::v1::RespondWorkflowTaskCompletedResponse,
|
|
37
38
|
},
|
|
38
39
|
};
|
|
39
|
-
use
|
|
40
|
+
use temporal_sdk_core_test_utils::{fanout_tasks, start_timer_cmd};
|
|
40
41
|
|
|
41
42
|
#[fixture(hist_batches = &[])]
|
|
42
43
|
fn single_timer_setup(hist_batches: &'static [usize]) -> CoreSDK {
|
|
@@ -74,15 +75,11 @@ async fn single_timer(#[case] core: CoreSDK, #[case] evict: WorkflowCachingPolic
|
|
|
74
75
|
evict,
|
|
75
76
|
&[
|
|
76
77
|
gen_assert_and_reply(
|
|
77
|
-
&job_assert!(
|
|
78
|
-
vec![
|
|
79
|
-
seq: 1,
|
|
80
|
-
..Default::default()
|
|
81
|
-
}
|
|
82
|
-
.into()],
|
|
78
|
+
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
79
|
+
vec![start_timer_cmd(1, Duration::from_secs(1))],
|
|
83
80
|
),
|
|
84
81
|
gen_assert_and_reply(
|
|
85
|
-
&job_assert!(
|
|
82
|
+
&job_assert!(workflow_activation_job::Variant::FireTimer(_)),
|
|
86
83
|
vec![CompleteWorkflowExecution { result: None }.into()],
|
|
87
84
|
),
|
|
88
85
|
],
|
|
@@ -103,7 +100,7 @@ async fn single_activity_completion(core: CoreSDK) {
|
|
|
103
100
|
NonSticky,
|
|
104
101
|
&[
|
|
105
102
|
gen_assert_and_reply(
|
|
106
|
-
&job_assert!(
|
|
103
|
+
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
107
104
|
vec![ScheduleActivity {
|
|
108
105
|
activity_id: "fake_activity".to_string(),
|
|
109
106
|
..Default::default()
|
|
@@ -111,7 +108,7 @@ async fn single_activity_completion(core: CoreSDK) {
|
|
|
111
108
|
.into()],
|
|
112
109
|
),
|
|
113
110
|
gen_assert_and_reply(
|
|
114
|
-
&job_assert!(
|
|
111
|
+
&job_assert!(workflow_activation_job::Variant::ResolveActivity(_)),
|
|
115
112
|
vec![CompleteWorkflowExecution { result: None }.into()],
|
|
116
113
|
),
|
|
117
114
|
],
|
|
@@ -137,18 +134,10 @@ async fn parallel_timer_test_across_wf_bridge(hist_batches: &'static [usize]) {
|
|
|
137
134
|
NonSticky,
|
|
138
135
|
&[
|
|
139
136
|
gen_assert_and_reply(
|
|
140
|
-
&job_assert!(
|
|
137
|
+
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
141
138
|
vec![
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
..Default::default()
|
|
145
|
-
}
|
|
146
|
-
.into(),
|
|
147
|
-
StartTimer {
|
|
148
|
-
seq: timer_2_id,
|
|
149
|
-
..Default::default()
|
|
150
|
-
}
|
|
151
|
-
.into(),
|
|
139
|
+
start_timer_cmd(timer_1_id, Duration::from_secs(1)),
|
|
140
|
+
start_timer_cmd(timer_2_id, Duration::from_secs(1)),
|
|
152
141
|
],
|
|
153
142
|
),
|
|
154
143
|
gen_assert_and_reply(
|
|
@@ -156,13 +145,13 @@ async fn parallel_timer_test_across_wf_bridge(hist_batches: &'static [usize]) {
|
|
|
156
145
|
assert_matches!(
|
|
157
146
|
res.jobs.as_slice(),
|
|
158
147
|
[
|
|
159
|
-
|
|
160
|
-
variant: Some(
|
|
148
|
+
WorkflowActivationJob {
|
|
149
|
+
variant: Some(workflow_activation_job::Variant::FireTimer(
|
|
161
150
|
FireTimer { seq: t1_id }
|
|
162
151
|
)),
|
|
163
152
|
},
|
|
164
|
-
|
|
165
|
-
variant: Some(
|
|
153
|
+
WorkflowActivationJob {
|
|
154
|
+
variant: Some(workflow_activation_job::Variant::FireTimer(
|
|
166
155
|
FireTimer { seq: t2_id }
|
|
167
156
|
)),
|
|
168
157
|
}
|
|
@@ -197,22 +186,14 @@ async fn timer_cancel(hist_batches: &'static [usize]) {
|
|
|
197
186
|
NonSticky,
|
|
198
187
|
&[
|
|
199
188
|
gen_assert_and_reply(
|
|
200
|
-
&job_assert!(
|
|
189
|
+
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
201
190
|
vec![
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
..Default::default()
|
|
205
|
-
}
|
|
206
|
-
.into(),
|
|
207
|
-
StartTimer {
|
|
208
|
-
seq: timer_id,
|
|
209
|
-
..Default::default()
|
|
210
|
-
}
|
|
211
|
-
.into(),
|
|
191
|
+
start_timer_cmd(cancel_timer_id, Duration::from_secs(1)),
|
|
192
|
+
start_timer_cmd(timer_id, Duration::from_secs(1)),
|
|
212
193
|
],
|
|
213
194
|
),
|
|
214
195
|
gen_assert_and_reply(
|
|
215
|
-
&job_assert!(
|
|
196
|
+
&job_assert!(workflow_activation_job::Variant::FireTimer(_)),
|
|
216
197
|
vec![
|
|
217
198
|
CancelTimer {
|
|
218
199
|
seq: cancel_timer_id,
|
|
@@ -242,7 +223,7 @@ async fn scheduled_activity_cancellation_try_cancel(hist_batches: &'static [usiz
|
|
|
242
223
|
NonSticky,
|
|
243
224
|
&[
|
|
244
225
|
gen_assert_and_reply(
|
|
245
|
-
&job_assert!(
|
|
226
|
+
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
246
227
|
vec![ScheduleActivity {
|
|
247
228
|
seq: activity_seq,
|
|
248
229
|
activity_id: activity_id.to_string(),
|
|
@@ -252,12 +233,12 @@ async fn scheduled_activity_cancellation_try_cancel(hist_batches: &'static [usiz
|
|
|
252
233
|
.into()],
|
|
253
234
|
),
|
|
254
235
|
gen_assert_and_reply(
|
|
255
|
-
&job_assert!(
|
|
236
|
+
&job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
|
|
256
237
|
vec![RequestCancelActivity { seq: activity_seq }.into()],
|
|
257
238
|
),
|
|
258
239
|
// Activity is getting resolved right away as we are in the TryCancel mode.
|
|
259
240
|
gen_assert_and_reply(
|
|
260
|
-
&job_assert!(
|
|
241
|
+
&job_assert!(workflow_activation_job::Variant::ResolveActivity(_)),
|
|
261
242
|
vec![CompleteWorkflowExecution { result: None }.into()],
|
|
262
243
|
),
|
|
263
244
|
],
|
|
@@ -279,7 +260,7 @@ async fn scheduled_activity_timeout(hist_batches: &'static [usize]) {
|
|
|
279
260
|
NonSticky,
|
|
280
261
|
&[
|
|
281
262
|
gen_assert_and_reply(
|
|
282
|
-
&job_assert!(
|
|
263
|
+
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
283
264
|
vec![ScheduleActivity {
|
|
284
265
|
seq: activity_seq,
|
|
285
266
|
activity_id: activity_id.to_string(),
|
|
@@ -293,12 +274,12 @@ async fn scheduled_activity_timeout(hist_batches: &'static [usize]) {
|
|
|
293
274
|
assert_matches!(
|
|
294
275
|
res.jobs.as_slice(),
|
|
295
276
|
[
|
|
296
|
-
|
|
297
|
-
variant: Some(
|
|
277
|
+
WorkflowActivationJob {
|
|
278
|
+
variant: Some(workflow_activation_job::Variant::ResolveActivity(
|
|
298
279
|
ResolveActivity {
|
|
299
280
|
seq,
|
|
300
|
-
result: Some(
|
|
301
|
-
status: Some(
|
|
281
|
+
result: Some(ActivityResolution {
|
|
282
|
+
status: Some(activity_resolution::Status::Failed(ar::Failure {
|
|
302
283
|
failure: Some(failure)
|
|
303
284
|
})),
|
|
304
285
|
})
|
|
@@ -332,7 +313,7 @@ async fn started_activity_timeout(hist_batches: &'static [usize]) {
|
|
|
332
313
|
NonSticky,
|
|
333
314
|
&[
|
|
334
315
|
gen_assert_and_reply(
|
|
335
|
-
&job_assert!(
|
|
316
|
+
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
336
317
|
vec![ScheduleActivity {
|
|
337
318
|
seq: activity_seq,
|
|
338
319
|
activity_id: activity_seq.to_string(),
|
|
@@ -343,26 +324,26 @@ async fn started_activity_timeout(hist_batches: &'static [usize]) {
|
|
|
343
324
|
// Activity is getting resolved right away as it has been timed out.
|
|
344
325
|
gen_assert_and_reply(
|
|
345
326
|
&|res| {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
}
|
|
359
|
-
)),
|
|
360
|
-
}
|
|
361
|
-
] => {
|
|
362
|
-
assert_eq!(failure.message, "Activity task timed out".to_string());
|
|
363
|
-
assert_eq!(*seq, activity_seq);
|
|
327
|
+
assert_matches!(
|
|
328
|
+
res.jobs.as_slice(),
|
|
329
|
+
[
|
|
330
|
+
WorkflowActivationJob {
|
|
331
|
+
variant: Some(workflow_activation_job::Variant::ResolveActivity(
|
|
332
|
+
ResolveActivity {
|
|
333
|
+
seq,
|
|
334
|
+
result: Some(ActivityResolution {
|
|
335
|
+
status: Some(activity_resolution::Status::Failed(ar::Failure {
|
|
336
|
+
failure: Some(failure)
|
|
337
|
+
})),
|
|
338
|
+
})
|
|
364
339
|
}
|
|
365
|
-
)
|
|
340
|
+
)),
|
|
341
|
+
}
|
|
342
|
+
] => {
|
|
343
|
+
assert_eq!(failure.message, "Activity task timed out".to_string());
|
|
344
|
+
assert_eq!(*seq, activity_seq);
|
|
345
|
+
}
|
|
346
|
+
);
|
|
366
347
|
},
|
|
367
348
|
vec![CompleteWorkflowExecution { result: None }.into()],
|
|
368
349
|
),
|
|
@@ -387,7 +368,7 @@ async fn cancelled_activity_timeout(hist_batches: &'static [usize]) {
|
|
|
387
368
|
NonSticky,
|
|
388
369
|
&[
|
|
389
370
|
gen_assert_and_reply(
|
|
390
|
-
&job_assert!(
|
|
371
|
+
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
391
372
|
vec![ScheduleActivity {
|
|
392
373
|
seq: activity_seq,
|
|
393
374
|
activity_id: activity_id.to_string(),
|
|
@@ -396,16 +377,16 @@ async fn cancelled_activity_timeout(hist_batches: &'static [usize]) {
|
|
|
396
377
|
.into()],
|
|
397
378
|
),
|
|
398
379
|
gen_assert_and_reply(
|
|
399
|
-
&job_assert!(
|
|
380
|
+
&job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
|
|
400
381
|
vec![RequestCancelActivity { seq: activity_seq }.into()],
|
|
401
382
|
),
|
|
402
383
|
// Activity is resolved right away as it has timed out.
|
|
403
384
|
gen_assert_and_reply(
|
|
404
|
-
&job_assert!(
|
|
385
|
+
&job_assert!(workflow_activation_job::Variant::ResolveActivity(
|
|
405
386
|
ResolveActivity {
|
|
406
387
|
seq: _,
|
|
407
|
-
result: Some(
|
|
408
|
-
status: Some(
|
|
388
|
+
result: Some(ActivityResolution {
|
|
389
|
+
status: Some(activity_resolution::Status::Cancelled(..)),
|
|
409
390
|
})
|
|
410
391
|
}
|
|
411
392
|
)),
|
|
@@ -491,7 +472,7 @@ async fn verify_activity_cancellation(
|
|
|
491
472
|
NonSticky,
|
|
492
473
|
&[
|
|
493
474
|
gen_assert_and_reply(
|
|
494
|
-
&job_assert!(
|
|
475
|
+
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
495
476
|
vec![ScheduleActivity {
|
|
496
477
|
seq: activity_seq,
|
|
497
478
|
activity_id: activity_seq.to_string(),
|
|
@@ -501,16 +482,16 @@ async fn verify_activity_cancellation(
|
|
|
501
482
|
.into()],
|
|
502
483
|
),
|
|
503
484
|
gen_assert_and_reply(
|
|
504
|
-
&job_assert!(
|
|
485
|
+
&job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
|
|
505
486
|
vec![RequestCancelActivity { seq: activity_seq }.into()],
|
|
506
487
|
),
|
|
507
488
|
// Activity should be resolved right away
|
|
508
489
|
gen_assert_and_reply(
|
|
509
|
-
&job_assert!(
|
|
490
|
+
&job_assert!(workflow_activation_job::Variant::ResolveActivity(
|
|
510
491
|
ResolveActivity {
|
|
511
492
|
seq: _,
|
|
512
|
-
result: Some(
|
|
513
|
-
status: Some(
|
|
493
|
+
result: Some(ActivityResolution {
|
|
494
|
+
status: Some(activity_resolution::Status::Cancelled(..)),
|
|
514
495
|
})
|
|
515
496
|
}
|
|
516
497
|
)),
|
|
@@ -559,7 +540,7 @@ async fn verify_activity_cancellation_wait_for_cancellation(activity_id: u32, co
|
|
|
559
540
|
NonSticky,
|
|
560
541
|
&[
|
|
561
542
|
gen_assert_and_reply(
|
|
562
|
-
&job_assert!(
|
|
543
|
+
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
563
544
|
vec![ScheduleActivity {
|
|
564
545
|
seq: activity_id,
|
|
565
546
|
activity_id: activity_id.to_string(),
|
|
@@ -569,21 +550,21 @@ async fn verify_activity_cancellation_wait_for_cancellation(activity_id: u32, co
|
|
|
569
550
|
.into()],
|
|
570
551
|
),
|
|
571
552
|
gen_assert_and_reply(
|
|
572
|
-
&job_assert!(
|
|
553
|
+
&job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
|
|
573
554
|
vec![RequestCancelActivity { seq: activity_id }.into()],
|
|
574
555
|
),
|
|
575
556
|
// Making sure that activity is not resolved until it's cancelled.
|
|
576
557
|
gen_assert_and_reply(
|
|
577
|
-
&job_assert!(
|
|
558
|
+
&job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
|
|
578
559
|
vec![],
|
|
579
560
|
),
|
|
580
561
|
// Now ActivityTaskCanceled has been processed and activity can be resolved.
|
|
581
562
|
gen_assert_and_reply(
|
|
582
|
-
&job_assert!(
|
|
563
|
+
&job_assert!(workflow_activation_job::Variant::ResolveActivity(
|
|
583
564
|
ResolveActivity {
|
|
584
565
|
seq: _,
|
|
585
|
-
result: Some(
|
|
586
|
-
status: Some(
|
|
566
|
+
result: Some(ActivityResolution {
|
|
567
|
+
status: Some(activity_resolution::Status::Cancelled(..)),
|
|
587
568
|
})
|
|
588
569
|
}
|
|
589
570
|
)),
|
|
@@ -615,8 +596,8 @@ async fn workflow_update_random_seed_on_workflow_reset() {
|
|
|
615
596
|
&|res| {
|
|
616
597
|
assert_matches!(
|
|
617
598
|
res.jobs.as_slice(),
|
|
618
|
-
[
|
|
619
|
-
variant: Some(
|
|
599
|
+
[WorkflowActivationJob {
|
|
600
|
+
variant: Some(workflow_activation_job::Variant::StartWorkflow(
|
|
620
601
|
StartWorkflow{randomness_seed, ..}
|
|
621
602
|
)),
|
|
622
603
|
}] => {
|
|
@@ -624,21 +605,17 @@ async fn workflow_update_random_seed_on_workflow_reset() {
|
|
|
624
605
|
}
|
|
625
606
|
);
|
|
626
607
|
},
|
|
627
|
-
vec![
|
|
628
|
-
seq: timer_1_id,
|
|
629
|
-
..Default::default()
|
|
630
|
-
}
|
|
631
|
-
.into()],
|
|
608
|
+
vec![start_timer_cmd(timer_1_id, Duration::from_secs(1))],
|
|
632
609
|
),
|
|
633
610
|
gen_assert_and_reply(
|
|
634
611
|
&|res| {
|
|
635
612
|
assert_matches!(
|
|
636
613
|
res.jobs.as_slice(),
|
|
637
|
-
[
|
|
638
|
-
variant: Some(
|
|
614
|
+
[WorkflowActivationJob {
|
|
615
|
+
variant: Some(workflow_activation_job::Variant::FireTimer(_),),
|
|
639
616
|
},
|
|
640
|
-
|
|
641
|
-
variant: Some(
|
|
617
|
+
WorkflowActivationJob {
|
|
618
|
+
variant: Some(workflow_activation_job::Variant::UpdateRandomSeed(
|
|
642
619
|
UpdateRandomSeed{randomness_seed})),
|
|
643
620
|
}] => {
|
|
644
621
|
assert_ne!(randomness_seed_from_start.load(Ordering::SeqCst),
|
|
@@ -669,13 +646,9 @@ async fn cancel_timer_before_sent_wf_bridge() {
|
|
|
669
646
|
&core,
|
|
670
647
|
NonSticky,
|
|
671
648
|
&[gen_assert_and_reply(
|
|
672
|
-
&job_assert!(
|
|
649
|
+
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
673
650
|
vec![
|
|
674
|
-
|
|
675
|
-
seq: cancel_timer_id,
|
|
676
|
-
..Default::default()
|
|
677
|
-
}
|
|
678
|
-
.into(),
|
|
651
|
+
start_timer_cmd(cancel_timer_id, Duration::from_secs(1)),
|
|
679
652
|
CancelTimer {
|
|
680
653
|
seq: cancel_timer_id,
|
|
681
654
|
}
|
|
@@ -718,15 +691,11 @@ async fn complete_activation_with_failure(
|
|
|
718
691
|
&[
|
|
719
692
|
gen_assert_and_reply(
|
|
720
693
|
&|_| {},
|
|
721
|
-
vec![
|
|
722
|
-
seq: timer_id,
|
|
723
|
-
..Default::default()
|
|
724
|
-
}
|
|
725
|
-
.into()],
|
|
694
|
+
vec![start_timer_cmd(timer_id, Duration::from_secs(1))],
|
|
726
695
|
),
|
|
727
696
|
gen_assert_and_fail(&|_| {}),
|
|
728
697
|
gen_assert_and_reply(
|
|
729
|
-
&job_assert!(
|
|
698
|
+
&job_assert!(workflow_activation_job::Variant::FireTimer(_)),
|
|
730
699
|
vec![CompleteWorkflowExecution { result: None }.into()],
|
|
731
700
|
),
|
|
732
701
|
],
|
|
@@ -749,15 +718,11 @@ async fn simple_timer_fail_wf_execution(hist_batches: &'static [usize]) {
|
|
|
749
718
|
NonSticky,
|
|
750
719
|
&[
|
|
751
720
|
gen_assert_and_reply(
|
|
752
|
-
&job_assert!(
|
|
753
|
-
vec![
|
|
754
|
-
seq: timer_id,
|
|
755
|
-
..Default::default()
|
|
756
|
-
}
|
|
757
|
-
.into()],
|
|
721
|
+
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
722
|
+
vec![start_timer_cmd(timer_id, Duration::from_secs(1))],
|
|
758
723
|
),
|
|
759
724
|
gen_assert_and_reply(
|
|
760
|
-
&job_assert!(
|
|
725
|
+
&job_assert!(workflow_activation_job::Variant::FireTimer(_)),
|
|
761
726
|
vec![FailWorkflowExecution {
|
|
762
727
|
failure: Some(Failure {
|
|
763
728
|
message: "I'm ded".to_string(),
|
|
@@ -784,14 +749,14 @@ async fn two_signals(hist_batches: &'static [usize]) {
|
|
|
784
749
|
NonSticky,
|
|
785
750
|
&[
|
|
786
751
|
gen_assert_and_reply(
|
|
787
|
-
&job_assert!(
|
|
752
|
+
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
788
753
|
// Task is completed with no commands
|
|
789
754
|
vec![],
|
|
790
755
|
),
|
|
791
756
|
gen_assert_and_reply(
|
|
792
757
|
&job_assert!(
|
|
793
|
-
|
|
794
|
-
|
|
758
|
+
workflow_activation_job::Variant::SignalWorkflow(_),
|
|
759
|
+
workflow_activation_job::Variant::SignalWorkflow(_)
|
|
795
760
|
),
|
|
796
761
|
vec![],
|
|
797
762
|
),
|
|
@@ -837,29 +802,21 @@ async fn workflow_failures_only_reported_once() {
|
|
|
837
802
|
&[
|
|
838
803
|
gen_assert_and_reply(
|
|
839
804
|
&|_| {},
|
|
840
|
-
vec![
|
|
841
|
-
seq: timer_1,
|
|
842
|
-
..Default::default()
|
|
843
|
-
}
|
|
844
|
-
.into()],
|
|
805
|
+
vec![start_timer_cmd(timer_1, Duration::from_secs(1))],
|
|
845
806
|
),
|
|
846
807
|
// Fail a few times in a row (only one of which should be reported)
|
|
847
808
|
gen_assert_and_fail(&|_| {}),
|
|
848
809
|
gen_assert_and_fail(&|_| {}),
|
|
849
810
|
gen_assert_and_fail(&|_| {}),
|
|
850
811
|
gen_assert_and_reply(
|
|
851
|
-
&job_assert!(
|
|
852
|
-
vec![
|
|
853
|
-
seq: timer_2,
|
|
854
|
-
..Default::default()
|
|
855
|
-
}
|
|
856
|
-
.into()],
|
|
812
|
+
&job_assert!(workflow_activation_job::Variant::FireTimer(_)),
|
|
813
|
+
vec![start_timer_cmd(timer_2, Duration::from_secs(1))],
|
|
857
814
|
),
|
|
858
815
|
// Again (a new fail should be reported here)
|
|
859
816
|
gen_assert_and_fail(&|_| {}),
|
|
860
817
|
gen_assert_and_fail(&|_| {}),
|
|
861
818
|
gen_assert_and_reply(
|
|
862
|
-
&job_assert!(
|
|
819
|
+
&job_assert!(workflow_activation_job::Variant::FireTimer(_)),
|
|
863
820
|
vec![CompleteWorkflowExecution { result: None }.into()],
|
|
864
821
|
),
|
|
865
822
|
],
|
|
@@ -908,14 +865,10 @@ async fn max_concurrent_wft_respected() {
|
|
|
908
865
|
let last_finisher = AtomicUsize::new(0);
|
|
909
866
|
let (_, mut r1) = tokio::join! {
|
|
910
867
|
async {
|
|
911
|
-
core.complete_workflow_activation(
|
|
868
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
912
869
|
TEST_Q,
|
|
913
870
|
r1.run_id,
|
|
914
|
-
|
|
915
|
-
seq: 1,
|
|
916
|
-
..Default::default()
|
|
917
|
-
}
|
|
918
|
-
.into())
|
|
871
|
+
start_timer_cmd(1, Duration::from_secs(1)))
|
|
919
872
|
).await.unwrap();
|
|
920
873
|
last_finisher.store(1, Ordering::SeqCst);
|
|
921
874
|
},
|
|
@@ -930,14 +883,10 @@ async fn max_concurrent_wft_respected() {
|
|
|
930
883
|
|
|
931
884
|
// Since we never did anything with r2, all subsequent activations should be for wf1
|
|
932
885
|
for i in 2..=20 {
|
|
933
|
-
core.complete_workflow_activation(
|
|
886
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
934
887
|
TEST_Q,
|
|
935
888
|
r1.run_id,
|
|
936
|
-
|
|
937
|
-
seq: i,
|
|
938
|
-
..Default::default()
|
|
939
|
-
}
|
|
940
|
-
.into(),
|
|
889
|
+
start_timer_cmd(i, Duration::from_secs(1)),
|
|
941
890
|
))
|
|
942
891
|
.await
|
|
943
892
|
.unwrap();
|
|
@@ -945,7 +894,7 @@ async fn max_concurrent_wft_respected() {
|
|
|
945
894
|
assert_eq!(r1.run_id, r1_run_id);
|
|
946
895
|
}
|
|
947
896
|
// Finish the tasks so we can shut down
|
|
948
|
-
core.complete_workflow_activation(
|
|
897
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
949
898
|
TEST_Q,
|
|
950
899
|
r1.run_id,
|
|
951
900
|
CompleteWorkflowExecution { result: None }.into(),
|
|
@@ -957,20 +906,16 @@ async fn max_concurrent_wft_respected() {
|
|
|
957
906
|
// We have to properly complete the outstanding task (or the mock will be confused why a task
|
|
958
907
|
// failure was reported)
|
|
959
908
|
let _ = core
|
|
960
|
-
.complete_workflow_activation(
|
|
909
|
+
.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
961
910
|
TEST_Q,
|
|
962
911
|
r2.run_id,
|
|
963
|
-
|
|
964
|
-
seq: 1,
|
|
965
|
-
..Default::default()
|
|
966
|
-
}
|
|
967
|
-
.into(),
|
|
912
|
+
start_timer_cmd(1, Duration::from_secs(1)),
|
|
968
913
|
))
|
|
969
914
|
.await;
|
|
970
915
|
// Get and complete eviction
|
|
971
916
|
let r2 = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
972
917
|
let _ = core
|
|
973
|
-
.complete_workflow_activation(
|
|
918
|
+
.complete_workflow_activation(WorkflowActivationCompletion::empty(TEST_Q, r2.run_id))
|
|
974
919
|
.await;
|
|
975
920
|
core.shutdown().await;
|
|
976
921
|
}
|
|
@@ -988,7 +933,7 @@ async fn activity_not_canceled_on_replay_repro(hist_batches: &'static [usize]) {
|
|
|
988
933
|
NonSticky,
|
|
989
934
|
&[
|
|
990
935
|
gen_assert_and_reply(
|
|
991
|
-
&job_assert!(
|
|
936
|
+
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
992
937
|
// Start timer and activity
|
|
993
938
|
vec![
|
|
994
939
|
ScheduleActivity {
|
|
@@ -998,31 +943,23 @@ async fn activity_not_canceled_on_replay_repro(hist_batches: &'static [usize]) {
|
|
|
998
943
|
..Default::default()
|
|
999
944
|
}
|
|
1000
945
|
.into(),
|
|
1001
|
-
|
|
1002
|
-
seq: 1,
|
|
1003
|
-
..Default::default()
|
|
1004
|
-
}
|
|
1005
|
-
.into(),
|
|
946
|
+
start_timer_cmd(1, Duration::from_secs(1)),
|
|
1006
947
|
],
|
|
1007
948
|
),
|
|
1008
949
|
gen_assert_and_reply(
|
|
1009
|
-
&job_assert!(
|
|
950
|
+
&job_assert!(workflow_activation_job::Variant::FireTimer(_)),
|
|
1010
951
|
vec![RequestCancelActivity { seq: activity_id }.into()],
|
|
1011
952
|
),
|
|
1012
953
|
gen_assert_and_reply(
|
|
1013
|
-
&job_assert!(
|
|
954
|
+
&job_assert!(workflow_activation_job::Variant::ResolveActivity(
|
|
1014
955
|
ResolveActivity {
|
|
1015
|
-
result: Some(
|
|
1016
|
-
status: Some(
|
|
956
|
+
result: Some(ActivityResolution {
|
|
957
|
+
status: Some(activity_resolution::Status::Cancelled(..)),
|
|
1017
958
|
}),
|
|
1018
959
|
..
|
|
1019
960
|
}
|
|
1020
961
|
)),
|
|
1021
|
-
vec![
|
|
1022
|
-
seq: 2,
|
|
1023
|
-
..Default::default()
|
|
1024
|
-
}
|
|
1025
|
-
.into()],
|
|
962
|
+
vec![start_timer_cmd(2, Duration::from_secs(1))],
|
|
1026
963
|
),
|
|
1027
964
|
],
|
|
1028
965
|
)
|
|
@@ -1042,7 +979,7 @@ async fn activity_not_canceled_when_also_completed_repro(hist_batches: &'static
|
|
|
1042
979
|
NonSticky,
|
|
1043
980
|
&[
|
|
1044
981
|
gen_assert_and_reply(
|
|
1045
|
-
&job_assert!(
|
|
982
|
+
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
1046
983
|
vec![ScheduleActivity {
|
|
1047
984
|
seq: activity_id,
|
|
1048
985
|
activity_id: activity_id.to_string(),
|
|
@@ -1052,21 +989,17 @@ async fn activity_not_canceled_when_also_completed_repro(hist_batches: &'static
|
|
|
1052
989
|
.into()],
|
|
1053
990
|
),
|
|
1054
991
|
gen_assert_and_reply(
|
|
1055
|
-
&job_assert!(
|
|
992
|
+
&job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
|
|
1056
993
|
vec![
|
|
1057
994
|
RequestCancelActivity { seq: activity_id }.into(),
|
|
1058
|
-
|
|
1059
|
-
seq: 2,
|
|
1060
|
-
..Default::default()
|
|
1061
|
-
}
|
|
1062
|
-
.into(),
|
|
995
|
+
start_timer_cmd(2, Duration::from_secs(1)),
|
|
1063
996
|
],
|
|
1064
997
|
),
|
|
1065
998
|
gen_assert_and_reply(
|
|
1066
|
-
&job_assert!(
|
|
999
|
+
&job_assert!(workflow_activation_job::Variant::ResolveActivity(
|
|
1067
1000
|
ResolveActivity {
|
|
1068
|
-
result: Some(
|
|
1069
|
-
status: Some(
|
|
1001
|
+
result: Some(ActivityResolution {
|
|
1002
|
+
status: Some(activity_resolution::Status::Cancelled(..)),
|
|
1070
1003
|
}),
|
|
1071
1004
|
..
|
|
1072
1005
|
}
|
|
@@ -1097,13 +1030,11 @@ async fn lots_of_workflows() {
|
|
|
1097
1030
|
while let Ok(wft) = core.poll_workflow_activation(TEST_Q).await {
|
|
1098
1031
|
let job = &wft.jobs[0];
|
|
1099
1032
|
let reply = match job.variant {
|
|
1100
|
-
Some(
|
|
1101
|
-
|
|
1102
|
-
..Default::default()
|
|
1033
|
+
Some(workflow_activation_job::Variant::StartWorkflow(_)) => {
|
|
1034
|
+
start_timer_cmd(1, Duration::from_secs(1))
|
|
1103
1035
|
}
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
core.complete_workflow_activation(WfActivationCompletion::empty(
|
|
1036
|
+
Some(workflow_activation_job::Variant::RemoveFromCache(_)) => {
|
|
1037
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::empty(
|
|
1107
1038
|
TEST_Q, wft.run_id,
|
|
1108
1039
|
))
|
|
1109
1040
|
.await
|
|
@@ -1112,7 +1043,7 @@ async fn lots_of_workflows() {
|
|
|
1112
1043
|
}
|
|
1113
1044
|
_ => CompleteWorkflowExecution { result: None }.into(),
|
|
1114
1045
|
};
|
|
1115
|
-
core.complete_workflow_activation(
|
|
1046
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
1116
1047
|
TEST_Q, wft.run_id, reply,
|
|
1117
1048
|
))
|
|
1118
1049
|
.await
|
|
@@ -1143,7 +1074,7 @@ async fn wft_timeout_repro(hist_batches: &'static [usize]) {
|
|
|
1143
1074
|
NonSticky,
|
|
1144
1075
|
&[
|
|
1145
1076
|
gen_assert_and_reply(
|
|
1146
|
-
&job_assert!(
|
|
1077
|
+
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
1147
1078
|
vec![ScheduleActivity {
|
|
1148
1079
|
seq: activity_id,
|
|
1149
1080
|
activity_id: activity_id.to_string(),
|
|
@@ -1154,11 +1085,11 @@ async fn wft_timeout_repro(hist_batches: &'static [usize]) {
|
|
|
1154
1085
|
),
|
|
1155
1086
|
gen_assert_and_reply(
|
|
1156
1087
|
&job_assert!(
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
result: Some(
|
|
1161
|
-
status: Some(
|
|
1088
|
+
workflow_activation_job::Variant::SignalWorkflow(_),
|
|
1089
|
+
workflow_activation_job::Variant::SignalWorkflow(_),
|
|
1090
|
+
workflow_activation_job::Variant::ResolveActivity(ResolveActivity {
|
|
1091
|
+
result: Some(ActivityResolution {
|
|
1092
|
+
status: Some(activity_resolution::Status::Completed(..)),
|
|
1162
1093
|
}),
|
|
1163
1094
|
..
|
|
1164
1095
|
})
|
|
@@ -1174,7 +1105,7 @@ async fn wft_timeout_repro(hist_batches: &'static [usize]) {
|
|
|
1174
1105
|
async fn complete_after_eviction() {
|
|
1175
1106
|
let wfid = "fake_wf_id";
|
|
1176
1107
|
let t = canned_histories::single_timer("1");
|
|
1177
|
-
let mut mock =
|
|
1108
|
+
let mut mock = mock_gateway();
|
|
1178
1109
|
mock.expect_complete_workflow_task().times(0);
|
|
1179
1110
|
let mock = single_hist_mock_sg(wfid, t, &[2], mock, true);
|
|
1180
1111
|
let core = mock_core(mock);
|
|
@@ -1183,14 +1114,10 @@ async fn complete_after_eviction() {
|
|
|
1183
1114
|
// We just got start workflow, immediately evict
|
|
1184
1115
|
core.request_workflow_eviction(TEST_Q, &activation.run_id);
|
|
1185
1116
|
// Original task must be completed before we get the eviction
|
|
1186
|
-
core.complete_workflow_activation(
|
|
1117
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
1187
1118
|
TEST_Q,
|
|
1188
1119
|
activation.run_id,
|
|
1189
|
-
|
|
1190
|
-
seq: 1,
|
|
1191
|
-
..Default::default()
|
|
1192
|
-
}
|
|
1193
|
-
.into(),
|
|
1120
|
+
start_timer_cmd(1, Duration::from_secs(1)),
|
|
1194
1121
|
))
|
|
1195
1122
|
.await
|
|
1196
1123
|
.unwrap();
|
|
@@ -1198,16 +1125,16 @@ async fn complete_after_eviction() {
|
|
|
1198
1125
|
assert_matches!(
|
|
1199
1126
|
eviction_activation.jobs.as_slice(),
|
|
1200
1127
|
[
|
|
1201
|
-
|
|
1202
|
-
variant: Some(
|
|
1128
|
+
WorkflowActivationJob {
|
|
1129
|
+
variant: Some(workflow_activation_job::Variant::FireTimer(_)),
|
|
1203
1130
|
},
|
|
1204
|
-
|
|
1205
|
-
variant: Some(
|
|
1131
|
+
WorkflowActivationJob {
|
|
1132
|
+
variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
|
|
1206
1133
|
}
|
|
1207
1134
|
]
|
|
1208
1135
|
);
|
|
1209
1136
|
// Complete the activation containing the eviction, the way we normally would have
|
|
1210
|
-
core.complete_workflow_activation(
|
|
1137
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
1211
1138
|
TEST_Q,
|
|
1212
1139
|
eviction_activation.run_id,
|
|
1213
1140
|
vec![CompleteWorkflowExecution { result: None }.into()],
|
|
@@ -1223,7 +1150,7 @@ async fn sends_appropriate_sticky_task_queue_responses() {
|
|
|
1223
1150
|
// include the information that tells the server to enqueue the next task on a sticky queue.
|
|
1224
1151
|
let wfid = "fake_wf_id";
|
|
1225
1152
|
let t = canned_histories::single_timer("1");
|
|
1226
|
-
let mut mock =
|
|
1153
|
+
let mut mock = mock_gateway();
|
|
1227
1154
|
mock.expect_complete_workflow_task()
|
|
1228
1155
|
.withf(|comp| comp.sticky_attributes.is_some())
|
|
1229
1156
|
.times(1)
|
|
@@ -1234,14 +1161,10 @@ async fn sends_appropriate_sticky_task_queue_responses() {
|
|
|
1234
1161
|
let core = mock_core(mock);
|
|
1235
1162
|
|
|
1236
1163
|
let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1237
|
-
core.complete_workflow_activation(
|
|
1164
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
1238
1165
|
TEST_Q,
|
|
1239
1166
|
activation.run_id,
|
|
1240
|
-
|
|
1241
|
-
seq: 1,
|
|
1242
|
-
..Default::default()
|
|
1243
|
-
}
|
|
1244
|
-
.into(),
|
|
1167
|
+
start_timer_cmd(1, Duration::from_secs(1)),
|
|
1245
1168
|
))
|
|
1246
1169
|
.await
|
|
1247
1170
|
.unwrap();
|
|
@@ -1249,37 +1172,33 @@ async fn sends_appropriate_sticky_task_queue_responses() {
|
|
|
1249
1172
|
}
|
|
1250
1173
|
|
|
1251
1174
|
#[tokio::test]
|
|
1252
|
-
#[should_panic(expected = "called more than 2 times")]
|
|
1253
1175
|
async fn new_server_work_while_eviction_outstanding_doesnt_overwrite_activation() {
|
|
1254
1176
|
let wfid = "fake_wf_id";
|
|
1255
1177
|
let t = canned_histories::single_timer("1");
|
|
1256
|
-
let mock =
|
|
1257
|
-
let mock = single_hist_mock_sg(wfid, t, &[1, 2], mock, true);
|
|
1178
|
+
let mock = single_hist_mock_sg(wfid, t, &[1, 2], mock_gateway(), false);
|
|
1258
1179
|
let core = mock_core(mock);
|
|
1259
1180
|
|
|
1260
1181
|
// Poll for and complete first workflow task
|
|
1261
1182
|
let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1262
|
-
core.complete_workflow_activation(
|
|
1183
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
1263
1184
|
TEST_Q,
|
|
1264
1185
|
activation.run_id,
|
|
1265
|
-
|
|
1266
|
-
seq: 1,
|
|
1267
|
-
..Default::default()
|
|
1268
|
-
}
|
|
1269
|
-
.into(),
|
|
1186
|
+
start_timer_cmd(1, Duration::from_secs(1)),
|
|
1270
1187
|
))
|
|
1271
1188
|
.await
|
|
1272
1189
|
.unwrap();
|
|
1273
1190
|
let eviction_activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1274
1191
|
assert_matches!(
|
|
1275
1192
|
eviction_activation.jobs.as_slice(),
|
|
1276
|
-
[
|
|
1277
|
-
variant: Some(
|
|
1193
|
+
[WorkflowActivationJob {
|
|
1194
|
+
variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
|
|
1278
1195
|
}]
|
|
1279
1196
|
);
|
|
1280
1197
|
// Poll again. We should not overwrite the eviction with the new work from the server to fire
|
|
1281
|
-
// the timer
|
|
1282
|
-
core.poll_workflow_activation(TEST_Q).await
|
|
1198
|
+
// the timer, so polling will try again, and run into the mock being out of responses.
|
|
1199
|
+
let act = core.poll_workflow_activation(TEST_Q).await;
|
|
1200
|
+
assert_matches!(act, Err(PollWfError::TonicError(err))
|
|
1201
|
+
if err.message() == NO_MORE_WORK_ERROR_MSG);
|
|
1283
1202
|
core.shutdown().await;
|
|
1284
1203
|
}
|
|
1285
1204
|
|
|
@@ -1318,7 +1237,7 @@ async fn buffered_work_drained_on_shutdown() {
|
|
|
1318
1237
|
))
|
|
1319
1238
|
.take(50),
|
|
1320
1239
|
);
|
|
1321
|
-
let mut mock =
|
|
1240
|
+
let mut mock = mock_gateway();
|
|
1322
1241
|
mock.expect_complete_workflow_task()
|
|
1323
1242
|
.returning(|_| Ok(RespondWorkflowTaskCompletedResponse::default()));
|
|
1324
1243
|
let mut mock = MocksHolder::from_gateway_with_responses(mock, tasks, []);
|
|
@@ -1332,7 +1251,7 @@ async fn buffered_work_drained_on_shutdown() {
|
|
|
1332
1251
|
// Now poll again, which will start spinning, and buffer the next WFT with timer fired in it
|
|
1333
1252
|
// - it won't stop spinning until the first task is complete
|
|
1334
1253
|
let t = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1335
|
-
core.complete_workflow_activation(
|
|
1254
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
1336
1255
|
TEST_Q,
|
|
1337
1256
|
t.run_id,
|
|
1338
1257
|
vec![CompleteWorkflowExecution { result: None }.into()],
|
|
@@ -1341,14 +1260,10 @@ async fn buffered_work_drained_on_shutdown() {
|
|
|
1341
1260
|
.unwrap();
|
|
1342
1261
|
};
|
|
1343
1262
|
let complete_first = async move {
|
|
1344
|
-
core.complete_workflow_activation(
|
|
1263
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
1345
1264
|
TEST_Q,
|
|
1346
1265
|
act1.run_id,
|
|
1347
|
-
|
|
1348
|
-
seq: 1,
|
|
1349
|
-
..Default::default()
|
|
1350
|
-
}
|
|
1351
|
-
.into(),
|
|
1266
|
+
start_timer_cmd(1, Duration::from_secs(1)),
|
|
1352
1267
|
))
|
|
1353
1268
|
.await
|
|
1354
1269
|
.unwrap();
|
|
@@ -1364,7 +1279,7 @@ async fn buffered_work_drained_on_shutdown() {
|
|
|
1364
1279
|
async fn buffering_tasks_doesnt_count_toward_outstanding_max() {
|
|
1365
1280
|
let wfid = "fake_wf_id";
|
|
1366
1281
|
let t = canned_histories::single_timer("1");
|
|
1367
|
-
let mock =
|
|
1282
|
+
let mock = mock_gateway();
|
|
1368
1283
|
let mut tasks = VecDeque::new();
|
|
1369
1284
|
// A way bigger task list than allowed outstanding tasks
|
|
1370
1285
|
tasks.extend(
|
|
@@ -1400,7 +1315,7 @@ async fn fail_wft_then_recover() {
|
|
|
1400
1315
|
t,
|
|
1401
1316
|
// We need to deliver all of history twice because of eviction
|
|
1402
1317
|
[ResponseType::AllHistory, ResponseType::AllHistory],
|
|
1403
|
-
|
|
1318
|
+
mock_gateway(),
|
|
1404
1319
|
);
|
|
1405
1320
|
mh.num_expected_fails = Some(1);
|
|
1406
1321
|
mh.expect_fail_wft_matcher =
|
|
@@ -1413,7 +1328,7 @@ async fn fail_wft_then_recover() {
|
|
|
1413
1328
|
|
|
1414
1329
|
let act = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1415
1330
|
// Start an activity instead of a timer, triggering nondeterminism error
|
|
1416
|
-
core.complete_workflow_activation(
|
|
1331
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
1417
1332
|
TEST_Q,
|
|
1418
1333
|
act.run_id.clone(),
|
|
1419
1334
|
vec![ScheduleActivity {
|
|
@@ -1429,35 +1344,34 @@ async fn fail_wft_then_recover() {
|
|
|
1429
1344
|
assert_eq!(evict_act.run_id, act.run_id);
|
|
1430
1345
|
assert_matches!(
|
|
1431
1346
|
evict_act.jobs.as_slice(),
|
|
1432
|
-
[
|
|
1433
|
-
variant: Some(
|
|
1347
|
+
[WorkflowActivationJob {
|
|
1348
|
+
variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
|
|
1434
1349
|
}]
|
|
1435
1350
|
);
|
|
1436
|
-
core.complete_workflow_activation(
|
|
1437
|
-
|
|
1438
|
-
.
|
|
1351
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::empty(
|
|
1352
|
+
TEST_Q,
|
|
1353
|
+
evict_act.run_id,
|
|
1354
|
+
))
|
|
1355
|
+
.await
|
|
1356
|
+
.unwrap();
|
|
1439
1357
|
|
|
1440
1358
|
// Workflow starting over, this time issue the right command
|
|
1441
1359
|
let act = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1442
|
-
core.complete_workflow_activation(
|
|
1360
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
1443
1361
|
TEST_Q,
|
|
1444
1362
|
act.run_id,
|
|
1445
|
-
vec![
|
|
1446
|
-
seq: 1,
|
|
1447
|
-
..Default::default()
|
|
1448
|
-
}
|
|
1449
|
-
.into()],
|
|
1363
|
+
vec![start_timer_cmd(1, Duration::from_secs(1))],
|
|
1450
1364
|
))
|
|
1451
1365
|
.await
|
|
1452
1366
|
.unwrap();
|
|
1453
1367
|
let act = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1454
1368
|
assert_matches!(
|
|
1455
1369
|
act.jobs.as_slice(),
|
|
1456
|
-
[
|
|
1457
|
-
variant: Some(
|
|
1370
|
+
[WorkflowActivationJob {
|
|
1371
|
+
variant: Some(workflow_activation_job::Variant::FireTimer(_)),
|
|
1458
1372
|
},]
|
|
1459
1373
|
);
|
|
1460
|
-
core.complete_workflow_activation(
|
|
1374
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
1461
1375
|
TEST_Q,
|
|
1462
1376
|
act.run_id,
|
|
1463
1377
|
vec![CompleteWorkflowExecution { result: None }.into()],
|
|
@@ -1476,12 +1390,8 @@ async fn poll_response_triggers_wf_error() {
|
|
|
1476
1390
|
t.add_full_wf_task();
|
|
1477
1391
|
t.add_workflow_execution_completed();
|
|
1478
1392
|
|
|
1479
|
-
let mut mh =
|
|
1480
|
-
"fake_wf_id",
|
|
1481
|
-
t,
|
|
1482
|
-
[ResponseType::AllHistory],
|
|
1483
|
-
MockServerGatewayApis::new(),
|
|
1484
|
-
);
|
|
1393
|
+
let mut mh =
|
|
1394
|
+
MockPollCfg::from_resp_batches("fake_wf_id", t, [ResponseType::AllHistory], mock_gateway());
|
|
1485
1395
|
// Since applying the poll response immediately generates an error core will start polling again
|
|
1486
1396
|
// Rather than panic on bad expectation we want to return the magic "no more work" error
|
|
1487
1397
|
mh.enforce_correct_number_of_polls = false;
|
|
@@ -1509,7 +1419,7 @@ async fn lang_slower_than_wft_timeouts() {
|
|
|
1509
1419
|
hist_to_poll_resp(&t, wfid.to_owned(), 1.into(), TEST_Q.to_string()),
|
|
1510
1420
|
hist_to_poll_resp(&t, wfid.to_owned(), 1.into(), TEST_Q.to_string()),
|
|
1511
1421
|
];
|
|
1512
|
-
let mut mock =
|
|
1422
|
+
let mut mock = mock_gateway();
|
|
1513
1423
|
mock.expect_complete_workflow_task()
|
|
1514
1424
|
.times(1)
|
|
1515
1425
|
.returning(|_| Err(tonic::Status::not_found("Workflow task not found.")));
|
|
@@ -1528,27 +1438,27 @@ async fn lang_slower_than_wft_timeouts() {
|
|
|
1528
1438
|
if err.message() == NO_MORE_WORK_ERROR_MSG);
|
|
1529
1439
|
// This completion runs into a workflow task not found error, since it's completing a stale
|
|
1530
1440
|
// task.
|
|
1531
|
-
core.complete_workflow_activation(
|
|
1441
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::empty(TEST_Q, wf_task.run_id))
|
|
1532
1442
|
.await
|
|
1533
1443
|
.unwrap();
|
|
1534
1444
|
// Now we should get an eviction
|
|
1535
1445
|
let wf_task = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1536
1446
|
assert_matches!(
|
|
1537
1447
|
wf_task.jobs.as_slice(),
|
|
1538
|
-
[
|
|
1539
|
-
variant: Some(
|
|
1448
|
+
[WorkflowActivationJob {
|
|
1449
|
+
variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
|
|
1540
1450
|
}]
|
|
1541
1451
|
);
|
|
1542
|
-
core.complete_workflow_activation(
|
|
1452
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::empty(TEST_Q, wf_task.run_id))
|
|
1543
1453
|
.await
|
|
1544
1454
|
.unwrap();
|
|
1545
1455
|
// The last WFT buffered should be applied now
|
|
1546
1456
|
let start_again = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1547
1457
|
assert_matches!(
|
|
1548
1458
|
start_again.jobs[0].variant,
|
|
1549
|
-
Some(
|
|
1459
|
+
Some(workflow_activation_job::Variant::StartWorkflow(_))
|
|
1550
1460
|
);
|
|
1551
|
-
core.complete_workflow_activation(
|
|
1461
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
1552
1462
|
TEST_Q,
|
|
1553
1463
|
start_again.run_id,
|
|
1554
1464
|
vec![CompleteWorkflowExecution { result: None }.into()],
|
|
@@ -1569,13 +1479,13 @@ async fn tries_cancel_of_completed_activity() {
|
|
|
1569
1479
|
t.add_activity_task_completed(scheduled_event_id, started_event_id, Default::default());
|
|
1570
1480
|
t.add_workflow_task_scheduled_and_started();
|
|
1571
1481
|
|
|
1572
|
-
let mock =
|
|
1482
|
+
let mock = mock_gateway();
|
|
1573
1483
|
let mut mock = single_hist_mock_sg("fake_wf_id", t, &[1, 2], mock, true);
|
|
1574
1484
|
mock.worker_cfg(TEST_Q, |cfg| cfg.max_cached_workflows = 1);
|
|
1575
1485
|
let core = mock_core(mock);
|
|
1576
1486
|
|
|
1577
1487
|
let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1578
|
-
core.complete_workflow_activation(
|
|
1488
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
1579
1489
|
TEST_Q,
|
|
1580
1490
|
activation.run_id,
|
|
1581
1491
|
ScheduleActivity {
|
|
@@ -1591,15 +1501,15 @@ async fn tries_cancel_of_completed_activity() {
|
|
|
1591
1501
|
assert_matches!(
|
|
1592
1502
|
activation.jobs.as_slice(),
|
|
1593
1503
|
[
|
|
1594
|
-
|
|
1595
|
-
variant: Some(
|
|
1504
|
+
WorkflowActivationJob {
|
|
1505
|
+
variant: Some(workflow_activation_job::Variant::SignalWorkflow(_)),
|
|
1596
1506
|
},
|
|
1597
|
-
|
|
1598
|
-
variant: Some(
|
|
1507
|
+
WorkflowActivationJob {
|
|
1508
|
+
variant: Some(workflow_activation_job::Variant::ResolveActivity(_)),
|
|
1599
1509
|
}
|
|
1600
1510
|
]
|
|
1601
1511
|
);
|
|
1602
|
-
core.complete_workflow_activation(
|
|
1512
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
1603
1513
|
TEST_Q,
|
|
1604
1514
|
activation.run_id,
|
|
1605
1515
|
vec![
|
|
@@ -1619,22 +1529,22 @@ async fn failing_wft_doesnt_eat_permit_forever() {
|
|
|
1619
1529
|
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
1620
1530
|
t.add_workflow_task_scheduled_and_started();
|
|
1621
1531
|
|
|
1622
|
-
let
|
|
1623
|
-
|
|
1624
|
-
let resps = (1..=(failures + 1)).map(|_| 1);
|
|
1625
|
-
let mock = MockServerGatewayApis::new();
|
|
1626
|
-
let mut mock = single_hist_mock_sg("fake_wf_id", t, resps, mock, true);
|
|
1532
|
+
let mock = mock_gateway();
|
|
1533
|
+
let mut mock = single_hist_mock_sg("fake_wf_id", t, [1, 1, 1], mock, true);
|
|
1627
1534
|
mock.worker_cfg(TEST_Q, |cfg| {
|
|
1628
1535
|
cfg.max_cached_workflows = 2;
|
|
1629
1536
|
cfg.max_outstanding_workflow_tasks = 2;
|
|
1630
1537
|
});
|
|
1538
|
+
let outstanding_mock_tasks = mock.outstanding_task_map.clone();
|
|
1631
1539
|
let core = mock_core(mock);
|
|
1632
1540
|
|
|
1633
|
-
|
|
1634
|
-
|
|
1541
|
+
let mut run_id = "".to_string();
|
|
1542
|
+
// Fail twice, verifying a permit is eaten. We cannot fail the same run more than twice in a row
|
|
1543
|
+
// because we purposefully time out rather than spamming.
|
|
1544
|
+
for _ in 1..=2 {
|
|
1635
1545
|
let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1636
1546
|
// Issue a nonsense completion that will trigger a WFT failure
|
|
1637
|
-
core.complete_workflow_activation(
|
|
1547
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
1638
1548
|
TEST_Q,
|
|
1639
1549
|
activation.run_id,
|
|
1640
1550
|
RequestCancelActivity { seq: 1 }.into(),
|
|
@@ -1644,18 +1554,31 @@ async fn failing_wft_doesnt_eat_permit_forever() {
|
|
|
1644
1554
|
let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1645
1555
|
assert_matches!(
|
|
1646
1556
|
activation.jobs.as_slice(),
|
|
1647
|
-
[
|
|
1648
|
-
variant: Some(
|
|
1557
|
+
[WorkflowActivationJob {
|
|
1558
|
+
variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
|
|
1649
1559
|
},]
|
|
1650
1560
|
);
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1561
|
+
run_id = activation.run_id.clone();
|
|
1562
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::empty(
|
|
1563
|
+
TEST_Q,
|
|
1564
|
+
activation.run_id,
|
|
1565
|
+
))
|
|
1566
|
+
.await
|
|
1567
|
+
.unwrap();
|
|
1654
1568
|
assert_eq!(core.outstanding_wfts(TEST_Q), 0);
|
|
1655
1569
|
assert_eq!(core.available_wft_permits(TEST_Q), 2);
|
|
1656
1570
|
}
|
|
1571
|
+
// We should be "out of work" because the mock service thinks we didn't complete the last task,
|
|
1572
|
+
// which we didn't, because we don't spam failures. The real server would eventually time out
|
|
1573
|
+
// the task. Mock doesn't understand that, so the WFT permit is released because eventually a
|
|
1574
|
+
// new one will be generated. We manually clear the mock's outstanding task list so the next
|
|
1575
|
+
// poll will work.
|
|
1576
|
+
outstanding_mock_tasks
|
|
1577
|
+
.unwrap()
|
|
1578
|
+
.write()
|
|
1579
|
+
.remove_by_left(&run_id);
|
|
1657
1580
|
let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1658
|
-
core.complete_workflow_activation(
|
|
1581
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
1659
1582
|
TEST_Q,
|
|
1660
1583
|
activation.run_id,
|
|
1661
1584
|
CompleteWorkflowExecution { result: None }.into(),
|
|
@@ -1688,7 +1611,7 @@ async fn cache_miss_doesnt_eat_permit_forever() {
|
|
|
1688
1611
|
// Last one to complete successfully
|
|
1689
1612
|
ResponseType::ToTaskNum(1),
|
|
1690
1613
|
],
|
|
1691
|
-
|
|
1614
|
+
mock_gateway(),
|
|
1692
1615
|
);
|
|
1693
1616
|
mh.num_expected_fails = Some(3);
|
|
1694
1617
|
mh.expect_fail_wft_matcher =
|
|
@@ -1703,20 +1626,26 @@ async fn cache_miss_doesnt_eat_permit_forever() {
|
|
|
1703
1626
|
for _ in 1..=3 {
|
|
1704
1627
|
// Start
|
|
1705
1628
|
let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1706
|
-
core.complete_workflow_activation(
|
|
1707
|
-
|
|
1708
|
-
.
|
|
1629
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::empty(
|
|
1630
|
+
TEST_Q,
|
|
1631
|
+
activation.run_id,
|
|
1632
|
+
))
|
|
1633
|
+
.await
|
|
1634
|
+
.unwrap();
|
|
1709
1635
|
// Evict
|
|
1710
1636
|
let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1711
1637
|
assert_matches!(
|
|
1712
1638
|
activation.jobs.as_slice(),
|
|
1713
|
-
[
|
|
1714
|
-
variant: Some(
|
|
1639
|
+
[WorkflowActivationJob {
|
|
1640
|
+
variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
|
|
1715
1641
|
},]
|
|
1716
1642
|
);
|
|
1717
|
-
core.complete_workflow_activation(
|
|
1718
|
-
|
|
1719
|
-
.
|
|
1643
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::empty(
|
|
1644
|
+
TEST_Q,
|
|
1645
|
+
activation.run_id,
|
|
1646
|
+
))
|
|
1647
|
+
.await
|
|
1648
|
+
.unwrap();
|
|
1720
1649
|
assert_eq!(core.outstanding_wfts(TEST_Q), 0);
|
|
1721
1650
|
assert_eq!(core.available_wft_permits(TEST_Q), 2);
|
|
1722
1651
|
// When we loop back up, the poll will trigger a cache miss, which we should immediately
|
|
@@ -1724,7 +1653,7 @@ async fn cache_miss_doesnt_eat_permit_forever() {
|
|
|
1724
1653
|
// history
|
|
1725
1654
|
}
|
|
1726
1655
|
let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1727
|
-
core.complete_workflow_activation(
|
|
1656
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
1728
1657
|
TEST_Q,
|
|
1729
1658
|
activation.run_id,
|
|
1730
1659
|
CompleteWorkflowExecution { result: None }.into(),
|
|
@@ -1734,3 +1663,62 @@ async fn cache_miss_doesnt_eat_permit_forever() {
|
|
|
1734
1663
|
|
|
1735
1664
|
core.shutdown().await;
|
|
1736
1665
|
}
|
|
1666
|
+
|
|
1667
|
+
/// This test verifies that WFTs which come as replies to completing a WFT are properly delivered
|
|
1668
|
+
/// via activation polling.
|
|
1669
|
+
#[tokio::test]
|
|
1670
|
+
async fn tasks_from_completion_are_delivered() {
|
|
1671
|
+
let wfid = "fake_wf_id";
|
|
1672
|
+
let mut t = TestHistoryBuilder::default();
|
|
1673
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
1674
|
+
t.add_full_wf_task();
|
|
1675
|
+
t.add_we_signaled("sig", vec![]);
|
|
1676
|
+
t.add_full_wf_task();
|
|
1677
|
+
t.add_workflow_execution_completed();
|
|
1678
|
+
|
|
1679
|
+
let tasks = [hist_to_poll_resp(
|
|
1680
|
+
&t,
|
|
1681
|
+
wfid.to_owned(),
|
|
1682
|
+
1.into(),
|
|
1683
|
+
TEST_Q.to_string(),
|
|
1684
|
+
)];
|
|
1685
|
+
let mut mock = mock_gateway();
|
|
1686
|
+
mock.expect_complete_workflow_task()
|
|
1687
|
+
.times(1)
|
|
1688
|
+
.returning(move |_| {
|
|
1689
|
+
Ok(RespondWorkflowTaskCompletedResponse {
|
|
1690
|
+
workflow_task: Some(hist_to_poll_resp(
|
|
1691
|
+
&t,
|
|
1692
|
+
wfid.to_owned(),
|
|
1693
|
+
2.into(),
|
|
1694
|
+
TEST_Q.to_string(),
|
|
1695
|
+
)),
|
|
1696
|
+
})
|
|
1697
|
+
});
|
|
1698
|
+
mock.expect_complete_workflow_task()
|
|
1699
|
+
.times(1)
|
|
1700
|
+
.returning(|_| Ok(Default::default()));
|
|
1701
|
+
let mut mock = MocksHolder::from_gateway_with_responses(mock, tasks, []);
|
|
1702
|
+
mock.worker_cfg(TEST_Q, |wc| wc.max_cached_workflows = 2);
|
|
1703
|
+
let core = mock_core(mock);
|
|
1704
|
+
|
|
1705
|
+
let wf_task = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1706
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::empty(TEST_Q, wf_task.run_id))
|
|
1707
|
+
.await
|
|
1708
|
+
.unwrap();
|
|
1709
|
+
let wf_task = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1710
|
+
assert_matches!(
|
|
1711
|
+
wf_task.jobs.as_slice(),
|
|
1712
|
+
[WorkflowActivationJob {
|
|
1713
|
+
variant: Some(workflow_activation_job::Variant::SignalWorkflow(_)),
|
|
1714
|
+
},]
|
|
1715
|
+
);
|
|
1716
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
1717
|
+
TEST_Q,
|
|
1718
|
+
wf_task.run_id,
|
|
1719
|
+
vec![CompleteWorkflowExecution { result: None }.into()],
|
|
1720
|
+
))
|
|
1721
|
+
.await
|
|
1722
|
+
.unwrap();
|
|
1723
|
+
core.shutdown().await;
|
|
1724
|
+
}
|