@temporalio/core-bridge 0.19.2 → 0.20.2
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 +90 -157
- package/Cargo.toml +1 -0
- package/index.d.ts +11 -27
- package/package.json +3 -3
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/releases/x86_64-apple-darwin/index.node +0 -0
- package/releases/x86_64-pc-windows-msvc/index.node +0 -0
- package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
- package/sdk-core/.buildkite/docker/Dockerfile +1 -1
- package/sdk-core/.buildkite/docker/docker-compose.yaml +1 -1
- package/sdk-core/.cargo/config.toml +1 -0
- package/sdk-core/CODEOWNERS +1 -1
- package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +119 -86
- package/sdk-core/bridge-ffi/src/lib.rs +311 -315
- package/sdk-core/bridge-ffi/src/wrappers.rs +108 -113
- package/sdk-core/client/Cargo.toml +13 -9
- package/sdk-core/client/LICENSE.txt +23 -0
- package/sdk-core/client/src/lib.rs +286 -174
- package/sdk-core/client/src/metrics.rs +86 -12
- package/sdk-core/client/src/raw.rs +566 -0
- package/sdk-core/client/src/retry.rs +137 -99
- package/sdk-core/core/Cargo.toml +15 -10
- package/sdk-core/core/LICENSE.txt +23 -0
- package/sdk-core/core/benches/workflow_replay.rs +79 -0
- package/sdk-core/core/src/abstractions.rs +38 -0
- package/sdk-core/core/src/core_tests/activity_tasks.rs +108 -182
- package/sdk-core/core/src/core_tests/child_workflows.rs +16 -11
- package/sdk-core/core/src/core_tests/determinism.rs +24 -12
- package/sdk-core/core/src/core_tests/local_activities.rs +53 -27
- package/sdk-core/core/src/core_tests/mod.rs +30 -43
- package/sdk-core/core/src/core_tests/queries.rs +82 -81
- package/sdk-core/core/src/core_tests/workers.rs +111 -296
- package/sdk-core/core/src/core_tests/workflow_cancels.rs +4 -4
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +257 -242
- package/sdk-core/core/src/lib.rs +73 -318
- package/sdk-core/core/src/pollers/mod.rs +4 -6
- package/sdk-core/core/src/pollers/poll_buffer.rs +20 -14
- package/sdk-core/core/src/protosext/mod.rs +7 -10
- package/sdk-core/core/src/replay/mod.rs +11 -150
- package/sdk-core/core/src/telemetry/metrics.rs +35 -2
- package/sdk-core/core/src/telemetry/mod.rs +49 -16
- package/sdk-core/core/src/telemetry/prometheus_server.rs +14 -35
- package/sdk-core/core/src/test_help/mod.rs +104 -170
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +57 -34
- package/sdk-core/core/src/worker/activities/local_activities.rs +95 -23
- package/sdk-core/core/src/worker/activities.rs +23 -16
- package/sdk-core/core/src/worker/client/mocks.rs +86 -0
- package/sdk-core/core/src/worker/client.rs +209 -0
- package/sdk-core/core/src/worker/mod.rs +207 -108
- package/sdk-core/core/src/workflow/driven_workflow.rs +21 -6
- package/sdk-core/core/src/workflow/history_update.rs +107 -24
- package/sdk-core/core/src/workflow/machines/activity_state_machine.rs +2 -3
- package/sdk-core/core/src/workflow/machines/child_workflow_state_machine.rs +2 -3
- package/sdk-core/core/src/workflow/machines/mod.rs +20 -17
- package/sdk-core/core/src/workflow/machines/signal_external_state_machine.rs +56 -19
- package/sdk-core/core/src/workflow/machines/transition_coverage.rs +5 -0
- package/sdk-core/core/src/workflow/machines/upsert_search_attributes_state_machine.rs +230 -22
- package/sdk-core/core/src/workflow/machines/workflow_machines.rs +81 -115
- package/sdk-core/core/src/workflow/machines/workflow_task_state_machine.rs +4 -4
- package/sdk-core/core/src/workflow/mod.rs +13 -1
- package/sdk-core/core/src/workflow/workflow_tasks/concurrency_manager.rs +70 -11
- package/sdk-core/core/src/workflow/workflow_tasks/mod.rs +65 -41
- package/sdk-core/core-api/Cargo.toml +9 -1
- package/sdk-core/core-api/LICENSE.txt +23 -0
- package/sdk-core/core-api/src/errors.rs +7 -38
- package/sdk-core/core-api/src/lib.rs +44 -52
- package/sdk-core/core-api/src/worker.rs +10 -2
- package/sdk-core/etc/deps.svg +127 -96
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +11 -7
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +10 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +6 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +6 -0
- package/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +6 -0
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +2 -1
- package/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +3 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +12 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +25 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +4 -0
- package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +19 -35
- package/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +2 -6
- package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +53 -11
- package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +14 -7
- package/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +3 -5
- package/sdk-core/sdk/Cargo.toml +16 -2
- package/sdk-core/sdk/LICENSE.txt +23 -0
- package/sdk-core/sdk/src/interceptors.rs +11 -0
- package/sdk-core/sdk/src/lib.rs +139 -151
- package/sdk-core/sdk/src/workflow_context/options.rs +86 -1
- package/sdk-core/sdk/src/workflow_context.rs +36 -17
- package/sdk-core/sdk/src/workflow_future.rs +19 -25
- package/sdk-core/sdk-core-protos/Cargo.toml +1 -1
- package/sdk-core/sdk-core-protos/build.rs +1 -0
- package/sdk-core/sdk-core-protos/src/history_info.rs +17 -4
- package/sdk-core/sdk-core-protos/src/lib.rs +251 -47
- package/sdk-core/test-utils/Cargo.toml +3 -1
- package/sdk-core/test-utils/src/canned_histories.rs +27 -0
- package/sdk-core/test-utils/src/histfetch.rs +3 -3
- package/sdk-core/test-utils/src/lib.rs +223 -68
- package/sdk-core/tests/integ_tests/client_tests.rs +27 -4
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +93 -14
- package/sdk-core/tests/integ_tests/polling_tests.rs +18 -12
- package/sdk-core/tests/integ_tests/queries_tests.rs +50 -53
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +117 -103
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +8 -1
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +10 -5
- package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +7 -1
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +32 -9
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +7 -1
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +76 -15
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +19 -3
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +39 -42
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +84 -0
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +30 -8
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +21 -6
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +26 -16
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +66 -0
- package/sdk-core/tests/integ_tests/workflow_tests.rs +78 -74
- package/sdk-core/tests/load_tests.rs +9 -6
- package/sdk-core/tests/main.rs +43 -10
- package/src/conversions.rs +7 -12
- package/src/lib.rs +322 -357
- package/sdk-core/client/src/mocks.rs +0 -167
- package/sdk-core/core/src/worker/dispatcher.rs +0 -171
- package/sdk-core/protos/local/temporal/sdk/core/bridge/service.proto +0 -61
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
use assert_matches::assert_matches;
|
|
2
2
|
use std::time::Duration;
|
|
3
|
+
use temporal_client::{WorkflowClientTrait, WorkflowOptions};
|
|
3
4
|
use temporal_sdk::{ActivityOptions, WfContext, WorkflowResult};
|
|
4
5
|
use temporal_sdk_core_protos::{
|
|
5
6
|
coresdk::{
|
|
@@ -23,7 +24,7 @@ use temporal_sdk_core_protos::{
|
|
|
23
24
|
},
|
|
24
25
|
};
|
|
25
26
|
use temporal_sdk_core_test_utils::{
|
|
26
|
-
init_core_and_create_wf, schedule_activity_cmd,
|
|
27
|
+
init_core_and_create_wf, schedule_activity_cmd, CoreWfStarter, WorkerTestHelpers,
|
|
27
28
|
};
|
|
28
29
|
use tokio::time::sleep;
|
|
29
30
|
|
|
@@ -50,7 +51,12 @@ async fn one_activity() {
|
|
|
50
51
|
);
|
|
51
52
|
|
|
52
53
|
worker
|
|
53
|
-
.submit_wf(
|
|
54
|
+
.submit_wf(
|
|
55
|
+
wf_name.to_owned(),
|
|
56
|
+
wf_name.to_owned(),
|
|
57
|
+
vec![],
|
|
58
|
+
WorkflowOptions::default(),
|
|
59
|
+
)
|
|
54
60
|
.await
|
|
55
61
|
.unwrap();
|
|
56
62
|
worker.run_until_done().await.unwrap();
|
|
@@ -58,25 +64,27 @@ async fn one_activity() {
|
|
|
58
64
|
|
|
59
65
|
#[tokio::test]
|
|
60
66
|
async fn activity_workflow() {
|
|
61
|
-
let
|
|
67
|
+
let mut starter = init_core_and_create_wf("activity_workflow").await;
|
|
68
|
+
let core = starter.get_worker().await;
|
|
69
|
+
let task_q = starter.get_task_queue();
|
|
62
70
|
let activity_id = "act-1";
|
|
63
|
-
let task = core.poll_workflow_activation(
|
|
71
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
64
72
|
// Complete workflow task and schedule activity
|
|
65
73
|
core.complete_workflow_activation(
|
|
66
74
|
schedule_activity_cmd(
|
|
67
75
|
0,
|
|
68
|
-
|
|
76
|
+
task_q,
|
|
69
77
|
activity_id,
|
|
70
78
|
ActivityCancellationType::TryCancel,
|
|
71
79
|
Duration::from_secs(60),
|
|
72
80
|
Duration::from_secs(60),
|
|
73
81
|
)
|
|
74
|
-
.into_completion(
|
|
82
|
+
.into_completion(task.run_id),
|
|
75
83
|
)
|
|
76
84
|
.await
|
|
77
85
|
.unwrap();
|
|
78
86
|
// Poll activity and verify that it's been scheduled with correct parameters
|
|
79
|
-
let task = core.poll_activity_task(
|
|
87
|
+
let task = core.poll_activity_task().await.unwrap();
|
|
80
88
|
assert_matches!(
|
|
81
89
|
task.variant,
|
|
82
90
|
Some(act_task::Variant::Start(start_activity)) => {
|
|
@@ -90,13 +98,12 @@ async fn activity_workflow() {
|
|
|
90
98
|
// Complete activity successfully.
|
|
91
99
|
core.complete_activity_task(ActivityTaskCompletion {
|
|
92
100
|
task_token: task.task_token,
|
|
93
|
-
task_queue: task_q.to_string(),
|
|
94
101
|
result: Some(ActivityExecutionResult::ok(response_payload.clone())),
|
|
95
102
|
})
|
|
96
103
|
.await
|
|
97
104
|
.unwrap();
|
|
98
105
|
// Poll workflow task and verify that activity has succeeded.
|
|
99
|
-
let task = core.poll_workflow_activation(
|
|
106
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
100
107
|
assert_matches!(
|
|
101
108
|
task.jobs.as_slice(),
|
|
102
109
|
[
|
|
@@ -114,30 +121,32 @@ async fn activity_workflow() {
|
|
|
114
121
|
assert_eq!(r, &response_payload);
|
|
115
122
|
}
|
|
116
123
|
);
|
|
117
|
-
core.complete_execution(&
|
|
124
|
+
core.complete_execution(&task.run_id).await;
|
|
118
125
|
}
|
|
119
126
|
|
|
120
127
|
#[tokio::test]
|
|
121
128
|
async fn activity_non_retryable_failure() {
|
|
122
|
-
let
|
|
129
|
+
let mut starter = init_core_and_create_wf("activity_non_retryable_failure").await;
|
|
130
|
+
let core = starter.get_worker().await;
|
|
131
|
+
let task_q = starter.get_task_queue();
|
|
123
132
|
let activity_id = "act-1";
|
|
124
|
-
let task = core.poll_workflow_activation(
|
|
133
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
125
134
|
// Complete workflow task and schedule activity
|
|
126
135
|
core.complete_workflow_activation(
|
|
127
136
|
schedule_activity_cmd(
|
|
128
137
|
0,
|
|
129
|
-
|
|
138
|
+
task_q,
|
|
130
139
|
activity_id,
|
|
131
140
|
ActivityCancellationType::TryCancel,
|
|
132
141
|
Duration::from_secs(60),
|
|
133
142
|
Duration::from_secs(60),
|
|
134
143
|
)
|
|
135
|
-
.into_completion(
|
|
144
|
+
.into_completion(task.run_id),
|
|
136
145
|
)
|
|
137
146
|
.await
|
|
138
147
|
.unwrap();
|
|
139
148
|
// Poll activity and verify that it's been scheduled with correct parameters
|
|
140
|
-
let task = core.poll_activity_task(
|
|
149
|
+
let task = core.poll_activity_task().await.unwrap();
|
|
141
150
|
assert_matches!(
|
|
142
151
|
task.variant,
|
|
143
152
|
Some(act_task::Variant::Start(start_activity)) => {
|
|
@@ -148,13 +157,12 @@ async fn activity_non_retryable_failure() {
|
|
|
148
157
|
let failure = Failure::application_failure("activity failed".to_string(), true);
|
|
149
158
|
core.complete_activity_task(ActivityTaskCompletion {
|
|
150
159
|
task_token: task.task_token,
|
|
151
|
-
task_queue: task_q.to_string(),
|
|
152
160
|
result: Some(ActivityExecutionResult::fail(failure.clone())),
|
|
153
161
|
})
|
|
154
162
|
.await
|
|
155
163
|
.unwrap();
|
|
156
164
|
// Poll workflow task and verify that activity has failed.
|
|
157
|
-
let task = core.poll_workflow_activation(
|
|
165
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
158
166
|
assert_matches!(
|
|
159
167
|
task.jobs.as_slice(),
|
|
160
168
|
[
|
|
@@ -185,30 +193,32 @@ async fn activity_non_retryable_failure() {
|
|
|
185
193
|
});
|
|
186
194
|
}
|
|
187
195
|
);
|
|
188
|
-
core.complete_execution(&
|
|
196
|
+
core.complete_execution(&task.run_id).await;
|
|
189
197
|
}
|
|
190
198
|
|
|
191
199
|
#[tokio::test]
|
|
192
200
|
async fn activity_retry() {
|
|
193
|
-
let
|
|
201
|
+
let mut starter = init_core_and_create_wf("activity_retry").await;
|
|
202
|
+
let core = starter.get_worker().await;
|
|
203
|
+
let task_q = starter.get_task_queue();
|
|
194
204
|
let activity_id = "act-1";
|
|
195
|
-
let task = core.poll_workflow_activation(
|
|
205
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
196
206
|
// Complete workflow task and schedule activity
|
|
197
207
|
core.complete_workflow_activation(
|
|
198
208
|
schedule_activity_cmd(
|
|
199
209
|
0,
|
|
200
|
-
|
|
210
|
+
task_q,
|
|
201
211
|
activity_id,
|
|
202
212
|
ActivityCancellationType::TryCancel,
|
|
203
213
|
Duration::from_secs(60),
|
|
204
214
|
Duration::from_secs(60),
|
|
205
215
|
)
|
|
206
|
-
.into_completion(
|
|
216
|
+
.into_completion(task.run_id),
|
|
207
217
|
)
|
|
208
218
|
.await
|
|
209
219
|
.unwrap();
|
|
210
220
|
// Poll activity 1st time
|
|
211
|
-
let task = core.poll_activity_task(
|
|
221
|
+
let task = core.poll_activity_task().await.unwrap();
|
|
212
222
|
assert_matches!(
|
|
213
223
|
task.variant,
|
|
214
224
|
Some(act_task::Variant::Start(start_activity)) => {
|
|
@@ -219,13 +229,12 @@ async fn activity_retry() {
|
|
|
219
229
|
let failure = Failure::application_failure("activity failed".to_string(), false);
|
|
220
230
|
core.complete_activity_task(ActivityTaskCompletion {
|
|
221
231
|
task_token: task.task_token,
|
|
222
|
-
task_queue: task_q.to_string(),
|
|
223
232
|
result: Some(ActivityExecutionResult::fail(failure)),
|
|
224
233
|
})
|
|
225
234
|
.await
|
|
226
235
|
.unwrap();
|
|
227
236
|
// Poll 2nd time
|
|
228
|
-
let task = core.poll_activity_task(
|
|
237
|
+
let task = core.poll_activity_task().await.unwrap();
|
|
229
238
|
assert_matches!(
|
|
230
239
|
task.variant,
|
|
231
240
|
Some(act_task::Variant::Start(start_activity)) => {
|
|
@@ -239,13 +248,12 @@ async fn activity_retry() {
|
|
|
239
248
|
};
|
|
240
249
|
core.complete_activity_task(ActivityTaskCompletion {
|
|
241
250
|
task_token: task.task_token,
|
|
242
|
-
task_queue: task_q.to_string(),
|
|
243
251
|
result: Some(ActivityExecutionResult::ok(response_payload.clone())),
|
|
244
252
|
})
|
|
245
253
|
.await
|
|
246
254
|
.unwrap();
|
|
247
255
|
// Poll workflow task and verify activity has succeeded.
|
|
248
|
-
let task = core.poll_workflow_activation(
|
|
256
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
249
257
|
assert_matches!(
|
|
250
258
|
task.jobs.as_slice(),
|
|
251
259
|
[
|
|
@@ -260,20 +268,22 @@ async fn activity_retry() {
|
|
|
260
268
|
assert_eq!(r, &response_payload);
|
|
261
269
|
}
|
|
262
270
|
);
|
|
263
|
-
core.complete_execution(&
|
|
271
|
+
core.complete_execution(&task.run_id).await;
|
|
264
272
|
}
|
|
265
273
|
|
|
266
274
|
#[tokio::test]
|
|
267
275
|
async fn activity_cancellation_try_cancel() {
|
|
268
|
-
let
|
|
276
|
+
let mut starter = init_core_and_create_wf("activity_cancellation_try_cancel").await;
|
|
277
|
+
let core = starter.get_worker().await;
|
|
278
|
+
let task_q = starter.get_task_queue();
|
|
269
279
|
let activity_id = "act-1";
|
|
270
|
-
let task = core.poll_workflow_activation(
|
|
280
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
271
281
|
// Complete workflow task and schedule activity and a timer that fires immediately
|
|
272
282
|
core.complete_workflow_activation(
|
|
273
283
|
vec![
|
|
274
284
|
schedule_activity_cmd(
|
|
275
285
|
0,
|
|
276
|
-
|
|
286
|
+
task_q,
|
|
277
287
|
activity_id,
|
|
278
288
|
ActivityCancellationType::TryCancel,
|
|
279
289
|
Duration::from_secs(60),
|
|
@@ -285,13 +295,13 @@ async fn activity_cancellation_try_cancel() {
|
|
|
285
295
|
}
|
|
286
296
|
.into(),
|
|
287
297
|
]
|
|
288
|
-
.into_completion(
|
|
298
|
+
.into_completion(task.run_id),
|
|
289
299
|
)
|
|
290
300
|
.await
|
|
291
301
|
.unwrap();
|
|
292
302
|
// Poll activity and verify that it's been scheduled with correct parameters, we don't expect to
|
|
293
303
|
// complete it in this test as activity is try-cancelled.
|
|
294
|
-
let activity_task = core.poll_activity_task(
|
|
304
|
+
let activity_task = core.poll_activity_task().await.unwrap();
|
|
295
305
|
assert_matches!(
|
|
296
306
|
activity_task.variant,
|
|
297
307
|
Some(act_task::Variant::Start(start_activity)) => {
|
|
@@ -299,7 +309,7 @@ async fn activity_cancellation_try_cancel() {
|
|
|
299
309
|
}
|
|
300
310
|
);
|
|
301
311
|
// Poll workflow task and verify that activity has failed.
|
|
302
|
-
let task = core.poll_workflow_activation(
|
|
312
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
303
313
|
assert_matches!(
|
|
304
314
|
task.jobs.as_slice(),
|
|
305
315
|
[
|
|
@@ -313,28 +323,29 @@ async fn activity_cancellation_try_cancel() {
|
|
|
313
323
|
}
|
|
314
324
|
);
|
|
315
325
|
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
316
|
-
&task_q,
|
|
317
326
|
task.run_id,
|
|
318
327
|
vec![RequestCancelActivity { seq: 0 }.into()],
|
|
319
328
|
))
|
|
320
329
|
.await
|
|
321
330
|
.unwrap();
|
|
322
|
-
let task = core.poll_workflow_activation(
|
|
323
|
-
core.complete_execution(&
|
|
331
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
332
|
+
core.complete_execution(&task.run_id).await;
|
|
324
333
|
}
|
|
325
334
|
|
|
326
335
|
#[tokio::test]
|
|
327
336
|
async fn activity_cancellation_plus_complete_doesnt_double_resolve() {
|
|
328
|
-
let
|
|
337
|
+
let mut starter =
|
|
329
338
|
init_core_and_create_wf("activity_cancellation_plus_complete_doesnt_double_resolve").await;
|
|
339
|
+
let core = starter.get_worker().await;
|
|
340
|
+
let task_q = starter.get_task_queue();
|
|
330
341
|
let activity_id = "act-1";
|
|
331
|
-
let task = core.poll_workflow_activation(
|
|
342
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
332
343
|
// Complete workflow task and schedule activity and a timer that fires immediately
|
|
333
344
|
core.complete_workflow_activation(
|
|
334
345
|
vec![
|
|
335
346
|
schedule_activity_cmd(
|
|
336
347
|
0,
|
|
337
|
-
|
|
348
|
+
task_q,
|
|
338
349
|
activity_id,
|
|
339
350
|
ActivityCancellationType::TryCancel,
|
|
340
351
|
Duration::from_secs(60),
|
|
@@ -346,13 +357,13 @@ async fn activity_cancellation_plus_complete_doesnt_double_resolve() {
|
|
|
346
357
|
}
|
|
347
358
|
.into(),
|
|
348
359
|
]
|
|
349
|
-
.into_completion(
|
|
360
|
+
.into_completion(task.run_id),
|
|
350
361
|
)
|
|
351
362
|
.await
|
|
352
363
|
.unwrap();
|
|
353
|
-
let activity_task = core.poll_activity_task(
|
|
364
|
+
let activity_task = core.poll_activity_task().await.unwrap();
|
|
354
365
|
assert_matches!(activity_task.variant, Some(act_task::Variant::Start(_)));
|
|
355
|
-
let task = core.poll_workflow_activation(
|
|
366
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
356
367
|
assert_matches!(
|
|
357
368
|
task.jobs.as_slice(),
|
|
358
369
|
[WorkflowActivationJob {
|
|
@@ -360,13 +371,12 @@ async fn activity_cancellation_plus_complete_doesnt_double_resolve() {
|
|
|
360
371
|
}]
|
|
361
372
|
);
|
|
362
373
|
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
363
|
-
&task_q,
|
|
364
374
|
task.run_id,
|
|
365
375
|
vec![RequestCancelActivity { seq: 0 }.into()],
|
|
366
376
|
))
|
|
367
377
|
.await
|
|
368
378
|
.unwrap();
|
|
369
|
-
let task = core.poll_workflow_activation(
|
|
379
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
370
380
|
// Should get cancel task
|
|
371
381
|
assert_matches!(
|
|
372
382
|
task.jobs.as_slice(),
|
|
@@ -384,7 +394,6 @@ async fn activity_cancellation_plus_complete_doesnt_double_resolve() {
|
|
|
384
394
|
// We need to complete the wf task to send the activity cancel command to the server, so start
|
|
385
395
|
// another short timer
|
|
386
396
|
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
387
|
-
&task_q,
|
|
388
397
|
task.run_id,
|
|
389
398
|
vec![StartTimer {
|
|
390
399
|
seq: 2,
|
|
@@ -397,7 +406,6 @@ async fn activity_cancellation_plus_complete_doesnt_double_resolve() {
|
|
|
397
406
|
// Now say the activity completes anyways
|
|
398
407
|
core.complete_activity_task(ActivityTaskCompletion {
|
|
399
408
|
task_token: activity_task.task_token,
|
|
400
|
-
task_queue: task_q.to_string(),
|
|
401
409
|
result: Some(ActivityExecutionResult::ok([1].into())),
|
|
402
410
|
})
|
|
403
411
|
.await
|
|
@@ -405,45 +413,47 @@ async fn activity_cancellation_plus_complete_doesnt_double_resolve() {
|
|
|
405
413
|
// Ensure we do not get a wakeup with the activity being resolved completed, and instead get
|
|
406
414
|
// the timer fired event (also wait for timer to fire)
|
|
407
415
|
sleep(Duration::from_secs(1)).await;
|
|
408
|
-
let task = core.poll_workflow_activation(
|
|
416
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
409
417
|
assert_matches!(
|
|
410
418
|
task.jobs.as_slice(),
|
|
411
419
|
[WorkflowActivationJob {
|
|
412
420
|
variant: Some(workflow_activation_job::Variant::FireTimer(_)),
|
|
413
421
|
}]
|
|
414
422
|
);
|
|
415
|
-
core.complete_execution(&
|
|
423
|
+
core.complete_execution(&task.run_id).await;
|
|
416
424
|
}
|
|
417
425
|
|
|
418
426
|
#[tokio::test]
|
|
419
427
|
async fn started_activity_timeout() {
|
|
420
|
-
let
|
|
428
|
+
let mut starter = init_core_and_create_wf("started_activity_timeout").await;
|
|
429
|
+
let core = starter.get_worker().await;
|
|
430
|
+
let task_q = starter.get_task_queue();
|
|
421
431
|
let activity_id = "act-1";
|
|
422
|
-
let task = core.poll_workflow_activation(
|
|
432
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
423
433
|
// Complete workflow task and schedule activity that times out in 1 second.
|
|
424
434
|
core.complete_workflow_activation(
|
|
425
435
|
schedule_activity_cmd(
|
|
426
436
|
0,
|
|
427
|
-
|
|
437
|
+
task_q,
|
|
428
438
|
activity_id,
|
|
429
439
|
ActivityCancellationType::TryCancel,
|
|
430
440
|
Duration::from_secs(1),
|
|
431
441
|
Duration::from_secs(60),
|
|
432
442
|
)
|
|
433
|
-
.into_completion(
|
|
443
|
+
.into_completion(task.run_id),
|
|
434
444
|
)
|
|
435
445
|
.await
|
|
436
446
|
.unwrap();
|
|
437
447
|
// Poll activity and verify that it's been scheduled with correct parameters, we don't expect to
|
|
438
448
|
// complete it in this test as activity is timed out after 1 second.
|
|
439
|
-
let activity_task = core.poll_activity_task(
|
|
449
|
+
let activity_task = core.poll_activity_task().await.unwrap();
|
|
440
450
|
assert_matches!(
|
|
441
451
|
activity_task.variant,
|
|
442
452
|
Some(act_task::Variant::Start(start_activity)) => {
|
|
443
453
|
assert_eq!(start_activity.activity_type, "test_activity".to_string())
|
|
444
454
|
}
|
|
445
455
|
);
|
|
446
|
-
let task = core.poll_workflow_activation(
|
|
456
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
447
457
|
assert_matches!(
|
|
448
458
|
task.jobs.as_slice(),
|
|
449
459
|
[
|
|
@@ -466,21 +476,23 @@ async fn started_activity_timeout() {
|
|
|
466
476
|
assert_eq!(*seq, 0);
|
|
467
477
|
}
|
|
468
478
|
);
|
|
469
|
-
core.complete_execution(&
|
|
479
|
+
core.complete_execution(&task.run_id).await;
|
|
470
480
|
}
|
|
471
481
|
|
|
472
482
|
#[tokio::test]
|
|
473
483
|
async fn activity_cancellation_wait_cancellation_completed() {
|
|
474
|
-
let
|
|
484
|
+
let mut starter =
|
|
475
485
|
init_core_and_create_wf("activity_cancellation_wait_cancellation_completed").await;
|
|
486
|
+
let core = starter.get_worker().await;
|
|
487
|
+
let task_q = starter.get_task_queue();
|
|
476
488
|
let activity_id = "act-1";
|
|
477
|
-
let task = core.poll_workflow_activation(
|
|
489
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
478
490
|
// Complete workflow task and schedule activity and a timer that fires immediately
|
|
479
491
|
core.complete_workflow_activation(
|
|
480
492
|
vec![
|
|
481
493
|
schedule_activity_cmd(
|
|
482
494
|
0,
|
|
483
|
-
|
|
495
|
+
task_q,
|
|
484
496
|
activity_id,
|
|
485
497
|
ActivityCancellationType::WaitCancellationCompleted,
|
|
486
498
|
Duration::from_secs(60),
|
|
@@ -492,13 +504,13 @@ async fn activity_cancellation_wait_cancellation_completed() {
|
|
|
492
504
|
}
|
|
493
505
|
.into(),
|
|
494
506
|
]
|
|
495
|
-
.into_completion(
|
|
507
|
+
.into_completion(task.run_id),
|
|
496
508
|
)
|
|
497
509
|
.await
|
|
498
510
|
.unwrap();
|
|
499
511
|
// Poll activity and verify that it's been scheduled with correct parameters, we don't expect to
|
|
500
512
|
// complete it in this test as activity is wait-cancelled.
|
|
501
|
-
let activity_task = core.poll_activity_task(
|
|
513
|
+
let activity_task = core.poll_activity_task().await.unwrap();
|
|
502
514
|
assert_matches!(
|
|
503
515
|
activity_task.variant,
|
|
504
516
|
Some(act_task::Variant::Start(start_activity)) => {
|
|
@@ -506,7 +518,7 @@ async fn activity_cancellation_wait_cancellation_completed() {
|
|
|
506
518
|
}
|
|
507
519
|
);
|
|
508
520
|
// Poll workflow task and verify that activity has failed.
|
|
509
|
-
let task = core.poll_workflow_activation(
|
|
521
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
510
522
|
assert_matches!(
|
|
511
523
|
task.jobs.as_slice(),
|
|
512
524
|
[
|
|
@@ -520,7 +532,6 @@ async fn activity_cancellation_wait_cancellation_completed() {
|
|
|
520
532
|
}
|
|
521
533
|
);
|
|
522
534
|
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
523
|
-
&task_q,
|
|
524
535
|
task.run_id,
|
|
525
536
|
vec![RequestCancelActivity { seq: 0 }.into()],
|
|
526
537
|
))
|
|
@@ -528,26 +539,27 @@ async fn activity_cancellation_wait_cancellation_completed() {
|
|
|
528
539
|
.unwrap();
|
|
529
540
|
core.complete_activity_task(ActivityTaskCompletion {
|
|
530
541
|
task_token: activity_task.task_token,
|
|
531
|
-
task_queue: task_q.to_string(),
|
|
532
542
|
result: Some(ActivityExecutionResult::cancel_from_details(None)),
|
|
533
543
|
})
|
|
534
544
|
.await
|
|
535
545
|
.unwrap();
|
|
536
|
-
let task = core.poll_workflow_activation(
|
|
537
|
-
core.complete_execution(&
|
|
546
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
547
|
+
core.complete_execution(&task.run_id).await;
|
|
538
548
|
}
|
|
539
549
|
|
|
540
550
|
#[tokio::test]
|
|
541
551
|
async fn activity_cancellation_abandon() {
|
|
542
|
-
let
|
|
552
|
+
let mut starter = init_core_and_create_wf("activity_cancellation_abandon").await;
|
|
553
|
+
let core = starter.get_worker().await;
|
|
554
|
+
let task_q = starter.get_task_queue();
|
|
543
555
|
let activity_id = "act-1";
|
|
544
|
-
let task = core.poll_workflow_activation(
|
|
556
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
545
557
|
// Complete workflow task and schedule activity and a timer that fires immediately
|
|
546
558
|
core.complete_workflow_activation(
|
|
547
559
|
vec![
|
|
548
560
|
schedule_activity_cmd(
|
|
549
561
|
0,
|
|
550
|
-
|
|
562
|
+
task_q,
|
|
551
563
|
activity_id,
|
|
552
564
|
ActivityCancellationType::Abandon,
|
|
553
565
|
Duration::from_secs(60),
|
|
@@ -559,13 +571,13 @@ async fn activity_cancellation_abandon() {
|
|
|
559
571
|
}
|
|
560
572
|
.into(),
|
|
561
573
|
]
|
|
562
|
-
.into_completion(
|
|
574
|
+
.into_completion(task.run_id),
|
|
563
575
|
)
|
|
564
576
|
.await
|
|
565
577
|
.unwrap();
|
|
566
578
|
// Poll activity and verify that it's been scheduled with correct parameters, we don't expect to
|
|
567
579
|
// complete it in this test as activity is abandoned.
|
|
568
|
-
let activity_task = core.poll_activity_task(
|
|
580
|
+
let activity_task = core.poll_activity_task().await.unwrap();
|
|
569
581
|
assert_matches!(
|
|
570
582
|
activity_task.variant,
|
|
571
583
|
Some(act_task::Variant::Start(start_activity)) => {
|
|
@@ -573,7 +585,7 @@ async fn activity_cancellation_abandon() {
|
|
|
573
585
|
}
|
|
574
586
|
);
|
|
575
587
|
// Poll workflow task and verify that activity has failed.
|
|
576
|
-
let task = core.poll_workflow_activation(
|
|
588
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
577
589
|
assert_matches!(
|
|
578
590
|
task.jobs.as_slice(),
|
|
579
591
|
[
|
|
@@ -587,7 +599,6 @@ async fn activity_cancellation_abandon() {
|
|
|
587
599
|
}
|
|
588
600
|
);
|
|
589
601
|
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
590
|
-
&task_q,
|
|
591
602
|
task.run_id,
|
|
592
603
|
vec![RequestCancelActivity { seq: 0 }.into()],
|
|
593
604
|
))
|
|
@@ -595,31 +606,33 @@ async fn activity_cancellation_abandon() {
|
|
|
595
606
|
.unwrap();
|
|
596
607
|
// Poll workflow task expecting that activation has been created by the state machine
|
|
597
608
|
// immediately after the cancellation request.
|
|
598
|
-
let task = core.poll_workflow_activation(
|
|
599
|
-
core.complete_execution(&
|
|
609
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
610
|
+
core.complete_execution(&task.run_id).await;
|
|
600
611
|
}
|
|
601
612
|
|
|
602
613
|
#[tokio::test]
|
|
603
614
|
async fn async_activity_completion_workflow() {
|
|
604
|
-
let
|
|
615
|
+
let mut starter = init_core_and_create_wf("async_activity_workflow").await;
|
|
616
|
+
let core = starter.get_worker().await;
|
|
617
|
+
let task_q = starter.get_task_queue();
|
|
605
618
|
let activity_id = "act-1";
|
|
606
|
-
let task = core.poll_workflow_activation(
|
|
619
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
607
620
|
// Complete workflow task and schedule activity
|
|
608
621
|
core.complete_workflow_activation(
|
|
609
622
|
schedule_activity_cmd(
|
|
610
623
|
0,
|
|
611
|
-
|
|
624
|
+
task_q,
|
|
612
625
|
activity_id,
|
|
613
626
|
ActivityCancellationType::TryCancel,
|
|
614
627
|
Duration::from_secs(60),
|
|
615
628
|
Duration::from_secs(60),
|
|
616
629
|
)
|
|
617
|
-
.into_completion(
|
|
630
|
+
.into_completion(task.run_id),
|
|
618
631
|
)
|
|
619
632
|
.await
|
|
620
633
|
.unwrap();
|
|
621
634
|
// Poll activity and verify that it's been scheduled with correct parameters
|
|
622
|
-
let task = core.poll_activity_task(
|
|
635
|
+
let task = core.poll_activity_task().await.unwrap();
|
|
623
636
|
assert_matches!(
|
|
624
637
|
task.variant,
|
|
625
638
|
Some(act_task::Variant::Start(start_activity)) => {
|
|
@@ -633,23 +646,24 @@ async fn async_activity_completion_workflow() {
|
|
|
633
646
|
// Complete activity asynchronously.
|
|
634
647
|
core.complete_activity_task(ActivityTaskCompletion {
|
|
635
648
|
task_token: task.task_token.clone(),
|
|
636
|
-
task_queue: task_q.to_string(),
|
|
637
649
|
result: Some(ActivityExecutionResult::will_complete_async()),
|
|
638
650
|
})
|
|
639
651
|
.await
|
|
640
652
|
.unwrap();
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
653
|
+
starter
|
|
654
|
+
.get_client()
|
|
655
|
+
.await
|
|
656
|
+
.complete_activity_task(
|
|
657
|
+
task.task_token.into(),
|
|
658
|
+
Some(Payloads {
|
|
659
|
+
payloads: vec![response_payload.clone().into()],
|
|
660
|
+
}),
|
|
661
|
+
)
|
|
662
|
+
.await
|
|
663
|
+
.unwrap();
|
|
650
664
|
|
|
651
665
|
// Poll workflow task and verify that activity has succeeded.
|
|
652
|
-
let task = core.poll_workflow_activation(
|
|
666
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
653
667
|
assert_matches!(
|
|
654
668
|
task.jobs.as_slice(),
|
|
655
669
|
[
|
|
@@ -665,15 +679,16 @@ async fn async_activity_completion_workflow() {
|
|
|
665
679
|
assert_eq!(r, &response_payload);
|
|
666
680
|
}
|
|
667
681
|
);
|
|
668
|
-
core.complete_execution(&
|
|
682
|
+
core.complete_execution(&task.run_id).await;
|
|
669
683
|
}
|
|
670
684
|
|
|
671
685
|
#[tokio::test]
|
|
672
686
|
async fn activity_cancelled_after_heartbeat_times_out() {
|
|
673
|
-
let
|
|
674
|
-
|
|
687
|
+
let mut starter = init_core_and_create_wf("activity_cancelled_after_heartbeat_times_out").await;
|
|
688
|
+
let core = starter.get_worker().await;
|
|
689
|
+
let task_q = starter.get_task_queue().to_string();
|
|
675
690
|
let activity_id = "act-1";
|
|
676
|
-
let task = core.poll_workflow_activation(
|
|
691
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
677
692
|
// Complete workflow task and schedule activity
|
|
678
693
|
core.complete_workflow_activation(
|
|
679
694
|
schedule_activity_cmd(
|
|
@@ -684,12 +699,12 @@ async fn activity_cancelled_after_heartbeat_times_out() {
|
|
|
684
699
|
Duration::from_secs(60),
|
|
685
700
|
Duration::from_secs(1),
|
|
686
701
|
)
|
|
687
|
-
.into_completion(
|
|
702
|
+
.into_completion(task.run_id),
|
|
688
703
|
)
|
|
689
704
|
.await
|
|
690
705
|
.unwrap();
|
|
691
706
|
// Poll activity and verify that it's been scheduled with correct parameters
|
|
692
|
-
let task = core.poll_activity_task(
|
|
707
|
+
let task = core.poll_activity_task().await.unwrap();
|
|
693
708
|
assert_matches!(
|
|
694
709
|
task.variant,
|
|
695
710
|
Some(act_task::Variant::Start(start_activity)) => {
|
|
@@ -700,30 +715,29 @@ async fn activity_cancelled_after_heartbeat_times_out() {
|
|
|
700
715
|
sleep(Duration::from_secs(2)).await;
|
|
701
716
|
core.record_activity_heartbeat(ActivityHeartbeat {
|
|
702
717
|
task_token: task.task_token.clone(),
|
|
703
|
-
task_queue: task_q.to_string(),
|
|
704
718
|
details: vec![],
|
|
705
719
|
});
|
|
706
720
|
|
|
707
721
|
// Verify activity got cancelled
|
|
708
|
-
let cancel_task = core.poll_activity_task(
|
|
722
|
+
let cancel_task = core.poll_activity_task().await.unwrap();
|
|
709
723
|
assert_eq!(cancel_task.task_token, task.task_token.clone());
|
|
710
724
|
assert_matches!(cancel_task.variant, Some(act_task::Variant::Cancel(_)));
|
|
711
725
|
|
|
712
726
|
// Complete activity with cancelled result
|
|
713
727
|
core.complete_activity_task(ActivityTaskCompletion {
|
|
714
728
|
task_token: task.task_token.clone(),
|
|
715
|
-
task_queue: task_q.to_string(),
|
|
716
729
|
result: Some(ActivityExecutionResult::cancel_from_details(None)),
|
|
717
730
|
})
|
|
718
731
|
.await
|
|
719
732
|
.unwrap();
|
|
720
733
|
|
|
721
734
|
// Verify shutdown completes
|
|
722
|
-
core.shutdown_worker(task_q.as_str()).await;
|
|
723
735
|
core.shutdown().await;
|
|
724
736
|
// Cleanup just in case
|
|
725
|
-
|
|
726
|
-
.
|
|
737
|
+
starter
|
|
738
|
+
.get_client()
|
|
739
|
+
.await
|
|
740
|
+
.terminate_workflow_execution(task_q.clone(), None)
|
|
727
741
|
.await
|
|
728
742
|
.unwrap();
|
|
729
743
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
use temporal_client::WorkflowOptions;
|
|
1
2
|
use temporal_sdk::{WfContext, WorkflowResult};
|
|
2
3
|
use temporal_sdk_core_protos::coresdk::common::NamespacedWorkflowExecution;
|
|
3
4
|
use temporal_sdk_core_test_utils::CoreWfStarter;
|
|
@@ -37,7 +38,12 @@ async fn sends_cancel_to_other_wf() {
|
|
|
37
38
|
worker.register_wf("receiver", cancel_receiver);
|
|
38
39
|
|
|
39
40
|
let receiver_run_id = worker
|
|
40
|
-
.submit_wf(
|
|
41
|
+
.submit_wf(
|
|
42
|
+
RECEIVER_WFID,
|
|
43
|
+
"receiver",
|
|
44
|
+
vec![],
|
|
45
|
+
WorkflowOptions::default(),
|
|
46
|
+
)
|
|
41
47
|
.await
|
|
42
48
|
.unwrap();
|
|
43
49
|
worker
|
|
@@ -45,6 +51,7 @@ async fn sends_cancel_to_other_wf() {
|
|
|
45
51
|
"sends-cancel-sender",
|
|
46
52
|
"sender",
|
|
47
53
|
vec![receiver_run_id.into()],
|
|
54
|
+
WorkflowOptions::default(),
|
|
48
55
|
)
|
|
49
56
|
.await
|
|
50
57
|
.unwrap();
|