@temporalio/core-bridge 1.4.4 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +327 -419
- package/Cargo.toml +1 -1
- package/index.js +25 -2
- package/lib/errors.d.ts +22 -0
- package/lib/errors.js +65 -0
- package/lib/errors.js.map +1 -0
- package/lib/index.d.ts +440 -0
- package/lib/index.js +8 -0
- package/lib/index.js.map +1 -0
- package/package.json +11 -5
- 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 +2 -2
- package/sdk-core/bridge-ffi/Cargo.toml +1 -1
- package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +0 -25
- package/sdk-core/bridge-ffi/src/lib.rs +29 -108
- package/sdk-core/bridge-ffi/src/wrappers.rs +35 -25
- package/sdk-core/client/Cargo.toml +1 -1
- package/sdk-core/client/src/lib.rs +12 -20
- package/sdk-core/client/src/raw.rs +9 -8
- package/sdk-core/client/src/retry.rs +100 -23
- package/sdk-core/core/Cargo.toml +5 -5
- package/sdk-core/core/benches/workflow_replay.rs +13 -10
- package/sdk-core/core/src/abstractions.rs +22 -22
- package/sdk-core/core/src/core_tests/activity_tasks.rs +1 -1
- package/sdk-core/core/src/core_tests/local_activities.rs +228 -6
- package/sdk-core/core/src/core_tests/queries.rs +247 -89
- package/sdk-core/core/src/core_tests/workers.rs +2 -2
- package/sdk-core/core/src/core_tests/workflow_cancels.rs +1 -1
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +46 -27
- package/sdk-core/core/src/lib.rs +139 -32
- package/sdk-core/core/src/replay/mod.rs +185 -41
- package/sdk-core/core/src/telemetry/log_export.rs +190 -0
- package/sdk-core/core/src/telemetry/metrics.rs +184 -139
- package/sdk-core/core/src/telemetry/mod.rs +296 -318
- package/sdk-core/core/src/telemetry/prometheus_server.rs +4 -3
- package/sdk-core/core/src/test_help/mod.rs +9 -7
- package/sdk-core/core/src/worker/activities/local_activities.rs +2 -1
- package/sdk-core/core/src/worker/activities.rs +40 -23
- package/sdk-core/core/src/worker/client/mocks.rs +1 -1
- package/sdk-core/core/src/worker/client.rs +30 -4
- package/sdk-core/core/src/worker/mod.rs +22 -18
- package/sdk-core/core/src/worker/workflow/driven_workflow.rs +10 -19
- package/sdk-core/core/src/worker/workflow/history_update.rs +99 -25
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +2 -6
- package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +18 -21
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +12 -38
- package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +178 -0
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +8 -2
- package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +232 -216
- package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +1 -6
- package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +4 -4
- package/sdk-core/core/src/worker/workflow/managed_run.rs +13 -5
- package/sdk-core/core/src/worker/workflow/mod.rs +61 -9
- package/sdk-core/core/src/worker/workflow/wft_poller.rs +2 -2
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +56 -11
- package/sdk-core/core-api/Cargo.toml +4 -3
- package/sdk-core/core-api/src/lib.rs +1 -43
- package/sdk-core/core-api/src/telemetry.rs +147 -0
- package/sdk-core/core-api/src/worker.rs +13 -0
- package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +1 -1
- package/sdk-core/histories/evict_while_la_running_no_interference-23_history.bin +0 -0
- package/sdk-core/histories/evict_while_la_running_no_interference-85_history.bin +0 -0
- package/sdk-core/protos/api_upstream/.github/CODEOWNERS +1 -1
- package/sdk-core/protos/api_upstream/buf.yaml +0 -3
- package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +3 -7
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +8 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +1 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +2 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +3 -0
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +13 -0
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +19 -59
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +0 -19
- package/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +108 -29
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +47 -8
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +15 -1
- package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +2 -0
- package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +8 -1
- package/sdk-core/sdk/src/interceptors.rs +36 -3
- package/sdk-core/sdk/src/lib.rs +7 -4
- package/sdk-core/sdk/src/workflow_context.rs +13 -2
- package/sdk-core/sdk-core-protos/src/history_builder.rs +47 -1
- package/sdk-core/sdk-core-protos/src/history_info.rs +22 -22
- package/sdk-core/sdk-core-protos/src/lib.rs +49 -27
- package/sdk-core/test-utils/Cargo.toml +1 -0
- package/sdk-core/test-utils/src/lib.rs +81 -29
- package/sdk-core/tests/integ_tests/metrics_tests.rs +37 -0
- package/sdk-core/tests/integ_tests/polling_tests.rs +0 -13
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +145 -4
- package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +53 -0
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +106 -20
- package/sdk-core/tests/integ_tests/workflow_tests.rs +18 -8
- package/sdk-core/tests/main.rs +6 -4
- package/src/conversions.rs +52 -47
- package/src/errors.rs +28 -86
- package/src/helpers.rs +3 -4
- package/src/lib.rs +2 -2
- package/src/runtime.rs +132 -61
- package/src/testing.rs +7 -4
- package/src/worker.rs +67 -50
- package/ts/errors.ts +55 -0
- package/{index.d.ts → ts/index.ts} +121 -15
- package/sdk-core/core/src/log_export.rs +0 -62
- package/sdk-core/core/src/worker/workflow/machines/mutable_side_effect_state_machine.rs +0 -127
- package/sdk-core/core/src/worker/workflow/machines/side_effect_state_machine.rs +0 -71
- package/sdk-core/protos/api_upstream/temporal/api/cluster/v1/message.proto +0 -83
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/cluster.proto +0 -40
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
use crate::{
|
|
2
2
|
test_help::{
|
|
3
3
|
build_mock_pollers, canned_histories, hist_to_poll_resp, mock_worker, single_hist_mock_sg,
|
|
4
|
-
MockPollCfg, ResponseType,
|
|
4
|
+
MockPollCfg, ResponseType,
|
|
5
5
|
},
|
|
6
6
|
worker::{client::mocks::mock_workflow_client, LEGACY_QUERY_ID},
|
|
7
7
|
};
|
|
@@ -16,22 +16,24 @@ use temporal_sdk_core_protos::{
|
|
|
16
16
|
remove_from_cache::EvictionReason, workflow_activation_job, WorkflowActivationJob,
|
|
17
17
|
},
|
|
18
18
|
workflow_commands::{
|
|
19
|
-
ActivityCancellationType, CompleteWorkflowExecution,
|
|
20
|
-
QueryResult, QuerySuccess, RequestCancelActivity,
|
|
19
|
+
query_result, ActivityCancellationType, CompleteWorkflowExecution,
|
|
20
|
+
ContinueAsNewWorkflowExecution, QueryResult, QuerySuccess, RequestCancelActivity,
|
|
21
21
|
},
|
|
22
22
|
workflow_completion::WorkflowActivationCompletion,
|
|
23
23
|
},
|
|
24
24
|
temporal::api::{
|
|
25
25
|
common::v1::Payload,
|
|
26
|
+
enums::v1::EventType,
|
|
26
27
|
failure::v1::Failure,
|
|
27
|
-
history::v1::History,
|
|
28
|
+
history::v1::{history_event, ActivityTaskCancelRequestedEventAttributes, History},
|
|
28
29
|
query::v1::WorkflowQuery,
|
|
29
30
|
workflowservice::v1::{
|
|
30
31
|
GetWorkflowExecutionHistoryResponse, RespondWorkflowTaskCompletedResponse,
|
|
31
32
|
},
|
|
32
33
|
},
|
|
34
|
+
TestHistoryBuilder,
|
|
33
35
|
};
|
|
34
|
-
use temporal_sdk_core_test_utils::{schedule_activity_cmd, start_timer_cmd};
|
|
36
|
+
use temporal_sdk_core_test_utils::{schedule_activity_cmd, start_timer_cmd, WorkerTestHelpers};
|
|
35
37
|
|
|
36
38
|
#[rstest::rstest]
|
|
37
39
|
#[case::with_history(true)]
|
|
@@ -44,9 +46,9 @@ async fn legacy_query(#[case] include_history: bool) {
|
|
|
44
46
|
let mut header = HashMap::new();
|
|
45
47
|
header.insert("head".to_string(), Payload::from(b"er"));
|
|
46
48
|
let tasks = [
|
|
47
|
-
hist_to_poll_resp(&t, wfid.to_owned(), 1.into()
|
|
49
|
+
hist_to_poll_resp(&t, wfid.to_owned(), 1.into()),
|
|
48
50
|
{
|
|
49
|
-
let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), 1.into()
|
|
51
|
+
let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), 1.into());
|
|
50
52
|
pr.query = Some(WorkflowQuery {
|
|
51
53
|
query_type: "query-type".to_string(),
|
|
52
54
|
query_args: Some(b"hi".into()),
|
|
@@ -57,7 +59,7 @@ async fn legacy_query(#[case] include_history: bool) {
|
|
|
57
59
|
}
|
|
58
60
|
pr
|
|
59
61
|
},
|
|
60
|
-
hist_to_poll_resp(&t, wfid.to_owned(), 2.into()
|
|
62
|
+
hist_to_poll_resp(&t, wfid.to_owned(), 2.into()),
|
|
61
63
|
];
|
|
62
64
|
let mut mock = MockPollCfg::from_resp_batches(wfid, t, tasks, mock_workflow_client());
|
|
63
65
|
mock.num_expected_legacy_query_resps = 1;
|
|
@@ -155,29 +157,21 @@ async fn new_queries(#[case] num_queries: usize) {
|
|
|
155
157
|
let t = canned_histories::single_timer("1");
|
|
156
158
|
let mut header = HashMap::new();
|
|
157
159
|
header.insert("head".to_string(), Payload::from(b"er"));
|
|
158
|
-
let tasks = VecDeque::from(vec![
|
|
159
|
-
hist_to_poll_resp(&t, wfid.to_owned(),
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
160
|
+
let tasks = VecDeque::from(vec![hist_to_poll_resp(&t, wfid.to_owned(), 1.into()), {
|
|
161
|
+
let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::OneTask(2));
|
|
162
|
+
pr.queries = HashMap::new();
|
|
163
|
+
for i in 1..=num_queries {
|
|
164
|
+
pr.queries.insert(
|
|
165
|
+
format!("q{}", i),
|
|
166
|
+
WorkflowQuery {
|
|
167
|
+
query_type: "query-type".to_string(),
|
|
168
|
+
query_args: Some(b"hi".into()),
|
|
169
|
+
header: Some(header.clone().into()),
|
|
170
|
+
},
|
|
166
171
|
);
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
format!("q{}", i),
|
|
171
|
-
WorkflowQuery {
|
|
172
|
-
query_type: "query-type".to_string(),
|
|
173
|
-
query_args: Some(b"hi".into()),
|
|
174
|
-
header: Some(header.clone().into()),
|
|
175
|
-
},
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
pr
|
|
179
|
-
},
|
|
180
|
-
]);
|
|
172
|
+
}
|
|
173
|
+
pr
|
|
174
|
+
}]);
|
|
181
175
|
let mut mock_client = mock_workflow_client();
|
|
182
176
|
mock_client.expect_respond_legacy_query().times(0);
|
|
183
177
|
let mut mock = single_hist_mock_sg(wfid, t, tasks, mock_client, true);
|
|
@@ -237,19 +231,16 @@ async fn new_queries(#[case] num_queries: usize) {
|
|
|
237
231
|
async fn legacy_query_failure_on_wft_failure() {
|
|
238
232
|
let wfid = "fake_wf_id";
|
|
239
233
|
let t = canned_histories::single_timer("1");
|
|
240
|
-
let tasks = VecDeque::from(vec![
|
|
241
|
-
hist_to_poll_resp(&t, wfid.to_owned(), 1.into()
|
|
242
|
-
{
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
pr
|
|
251
|
-
},
|
|
252
|
-
]);
|
|
234
|
+
let tasks = VecDeque::from(vec![hist_to_poll_resp(&t, wfid.to_owned(), 1.into()), {
|
|
235
|
+
let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), 1.into());
|
|
236
|
+
pr.query = Some(WorkflowQuery {
|
|
237
|
+
query_type: "query-type".to_string(),
|
|
238
|
+
query_args: Some(b"hi".into()),
|
|
239
|
+
header: None,
|
|
240
|
+
});
|
|
241
|
+
pr.history = Some(History { events: vec![] });
|
|
242
|
+
pr
|
|
243
|
+
}]);
|
|
253
244
|
let mut mock = MockPollCfg::from_resp_batches(wfid, t, tasks, mock_workflow_client());
|
|
254
245
|
mock.num_expected_legacy_query_resps = 1;
|
|
255
246
|
let mut mock = build_mock_pollers(mock);
|
|
@@ -292,12 +283,7 @@ async fn query_failure_because_nondeterminism(#[values(true, false)] legacy: boo
|
|
|
292
283
|
let wfid = "fake_wf_id";
|
|
293
284
|
let t = canned_histories::single_timer("1");
|
|
294
285
|
let tasks = [{
|
|
295
|
-
let mut pr = hist_to_poll_resp(
|
|
296
|
-
&t,
|
|
297
|
-
wfid.to_owned(),
|
|
298
|
-
ResponseType::AllHistory,
|
|
299
|
-
TEST_Q.to_string(),
|
|
300
|
-
);
|
|
286
|
+
let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::AllHistory);
|
|
301
287
|
if legacy {
|
|
302
288
|
pr.query = Some(WorkflowQuery {
|
|
303
289
|
query_type: "query-type".to_string(),
|
|
@@ -356,12 +342,7 @@ async fn legacy_query_after_complete(#[values(false, true)] full_history: bool)
|
|
|
356
342
|
t
|
|
357
343
|
};
|
|
358
344
|
let query_with_hist_task = {
|
|
359
|
-
let mut pr = hist_to_poll_resp(
|
|
360
|
-
&t,
|
|
361
|
-
wfid.to_owned(),
|
|
362
|
-
ResponseType::AllHistory,
|
|
363
|
-
TEST_Q.to_string(),
|
|
364
|
-
);
|
|
345
|
+
let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::AllHistory);
|
|
365
346
|
pr.query = Some(WorkflowQuery {
|
|
366
347
|
query_type: "query-type".to_string(),
|
|
367
348
|
query_args: Some(b"hi".into()),
|
|
@@ -375,15 +356,7 @@ async fn legacy_query_after_complete(#[values(false, true)] full_history: bool)
|
|
|
375
356
|
let mut tasks = if full_history {
|
|
376
357
|
vec![]
|
|
377
358
|
} else {
|
|
378
|
-
vec![
|
|
379
|
-
hist_to_poll_resp(
|
|
380
|
-
&t,
|
|
381
|
-
wfid.to_owned(),
|
|
382
|
-
ResponseType::AllHistory,
|
|
383
|
-
TEST_Q.to_string(),
|
|
384
|
-
)
|
|
385
|
-
.resp,
|
|
386
|
-
]
|
|
359
|
+
vec![hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::AllHistory).resp]
|
|
387
360
|
};
|
|
388
361
|
tasks.extend([query_with_hist_task.clone(), query_with_hist_task]);
|
|
389
362
|
|
|
@@ -456,29 +429,14 @@ async fn query_cache_miss_causes_page_fetch_dont_reply_wft_too_early(
|
|
|
456
429
|
QueryHists::Empty => {
|
|
457
430
|
// Create a no-history poll response. This happens to be easiest to do by just ripping
|
|
458
431
|
// out the history after making a normal one.
|
|
459
|
-
let mut pr = hist_to_poll_resp(
|
|
460
|
-
&t,
|
|
461
|
-
wfid.to_owned(),
|
|
462
|
-
ResponseType::AllHistory,
|
|
463
|
-
TEST_Q.to_string(),
|
|
464
|
-
);
|
|
432
|
+
let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::AllHistory);
|
|
465
433
|
pr.history = Some(Default::default());
|
|
466
434
|
pr
|
|
467
435
|
}
|
|
468
|
-
QueryHists::Full => hist_to_poll_resp(
|
|
469
|
-
&t,
|
|
470
|
-
wfid.to_owned(),
|
|
471
|
-
ResponseType::AllHistory,
|
|
472
|
-
TEST_Q.to_string(),
|
|
473
|
-
),
|
|
436
|
+
QueryHists::Full => hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::AllHistory),
|
|
474
437
|
QueryHists::Partial => {
|
|
475
438
|
// Create a partial task
|
|
476
|
-
hist_to_poll_resp(
|
|
477
|
-
&t,
|
|
478
|
-
wfid.to_owned(),
|
|
479
|
-
ResponseType::OneTask(2),
|
|
480
|
-
TEST_Q.to_string(),
|
|
481
|
-
)
|
|
439
|
+
hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::OneTask(2))
|
|
482
440
|
}
|
|
483
441
|
};
|
|
484
442
|
pr.queries = HashMap::new();
|
|
@@ -579,12 +537,7 @@ async fn query_replay_with_continue_as_new_doesnt_reply_empty_command() {
|
|
|
579
537
|
let wfid = "fake_wf_id";
|
|
580
538
|
let t = canned_histories::single_timer("1");
|
|
581
539
|
let query_with_hist_task = {
|
|
582
|
-
let mut pr = hist_to_poll_resp(
|
|
583
|
-
&t,
|
|
584
|
-
wfid.to_owned(),
|
|
585
|
-
ResponseType::ToTaskNum(1),
|
|
586
|
-
TEST_Q.to_string(),
|
|
587
|
-
);
|
|
540
|
+
let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::ToTaskNum(1));
|
|
588
541
|
pr.queries = HashMap::new();
|
|
589
542
|
pr.queries.insert(
|
|
590
543
|
"the-query".to_string(),
|
|
@@ -682,7 +635,7 @@ async fn legacy_query_response_gets_not_found_not_fatal() {
|
|
|
682
635
|
let wfid = "fake_wf_id";
|
|
683
636
|
let t = canned_histories::single_timer("1");
|
|
684
637
|
let tasks = [{
|
|
685
|
-
let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), 1.into()
|
|
638
|
+
let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), 1.into());
|
|
686
639
|
pr.query = Some(WorkflowQuery {
|
|
687
640
|
query_type: "query-type".to_string(),
|
|
688
641
|
query_args: Some(b"hi".into()),
|
|
@@ -734,3 +687,208 @@ async fn legacy_query_response_gets_not_found_not_fatal() {
|
|
|
734
687
|
|
|
735
688
|
core.shutdown().await;
|
|
736
689
|
}
|
|
690
|
+
|
|
691
|
+
#[tokio::test]
|
|
692
|
+
async fn new_query_fail() {
|
|
693
|
+
let wfid = "fake_wf_id";
|
|
694
|
+
let t = canned_histories::single_timer("1");
|
|
695
|
+
let tasks = VecDeque::from(vec![{
|
|
696
|
+
let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), 1.into());
|
|
697
|
+
pr.queries = HashMap::new();
|
|
698
|
+
pr.queries.insert(
|
|
699
|
+
"q1".to_string(),
|
|
700
|
+
WorkflowQuery {
|
|
701
|
+
query_type: "query-type".to_string(),
|
|
702
|
+
query_args: Some(b"hi".into()),
|
|
703
|
+
header: Default::default(),
|
|
704
|
+
},
|
|
705
|
+
);
|
|
706
|
+
pr
|
|
707
|
+
}]);
|
|
708
|
+
let mut mock_client = mock_workflow_client();
|
|
709
|
+
mock_client
|
|
710
|
+
.expect_complete_workflow_task()
|
|
711
|
+
.times(1)
|
|
712
|
+
.returning(|resp| {
|
|
713
|
+
// Verify there is a failed query response along w/ start timer cmd
|
|
714
|
+
assert_eq!(resp.commands.len(), 1);
|
|
715
|
+
assert_matches!(
|
|
716
|
+
resp.query_responses.as_slice(),
|
|
717
|
+
&[QueryResult {
|
|
718
|
+
variant: Some(query_result::Variant::Failed(_)),
|
|
719
|
+
..
|
|
720
|
+
}]
|
|
721
|
+
);
|
|
722
|
+
Ok(RespondWorkflowTaskCompletedResponse::default())
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
let mut mock = single_hist_mock_sg(wfid, t, tasks, mock_client, true);
|
|
726
|
+
mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
|
|
727
|
+
let core = mock_worker(mock);
|
|
728
|
+
|
|
729
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
730
|
+
assert_matches!(
|
|
731
|
+
task.jobs[0],
|
|
732
|
+
WorkflowActivationJob {
|
|
733
|
+
variant: Some(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
734
|
+
}
|
|
735
|
+
);
|
|
736
|
+
|
|
737
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
738
|
+
task.run_id,
|
|
739
|
+
start_timer_cmd(1, Duration::from_secs(1)),
|
|
740
|
+
))
|
|
741
|
+
.await
|
|
742
|
+
.unwrap();
|
|
743
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
744
|
+
assert_matches!(
|
|
745
|
+
task.jobs[0],
|
|
746
|
+
WorkflowActivationJob {
|
|
747
|
+
variant: Some(workflow_activation_job::Variant::QueryWorkflow(_)),
|
|
748
|
+
}
|
|
749
|
+
);
|
|
750
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
751
|
+
task.run_id,
|
|
752
|
+
QueryResult {
|
|
753
|
+
query_id: "q1".to_string(),
|
|
754
|
+
variant: Some(query_result::Variant::Failed("ahhh".into())),
|
|
755
|
+
}
|
|
756
|
+
.into(),
|
|
757
|
+
))
|
|
758
|
+
.await
|
|
759
|
+
.unwrap();
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
/// This test verifies that if we get a task with a legacy query in it while in the middle of
|
|
763
|
+
/// processing some local-only work (in this case, resolving an activity as soon as it was
|
|
764
|
+
/// cancelled) that we do not combine the legacy query with the resolve job.
|
|
765
|
+
#[tokio::test]
|
|
766
|
+
async fn legacy_query_combined_with_timer_fire_repro() {
|
|
767
|
+
let wfid = "fake_wf_id";
|
|
768
|
+
let mut t = TestHistoryBuilder::default();
|
|
769
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
770
|
+
t.add_full_wf_task();
|
|
771
|
+
let scheduled_event_id = t.add_activity_task_scheduled("1");
|
|
772
|
+
let timer_started_event_id = t.add_get_event_id(EventType::TimerStarted, None);
|
|
773
|
+
t.add_timer_fired(timer_started_event_id, "1".to_string());
|
|
774
|
+
t.add_full_wf_task();
|
|
775
|
+
t.add(
|
|
776
|
+
EventType::ActivityTaskCancelRequested,
|
|
777
|
+
history_event::Attributes::ActivityTaskCancelRequestedEventAttributes(
|
|
778
|
+
ActivityTaskCancelRequestedEventAttributes {
|
|
779
|
+
scheduled_event_id,
|
|
780
|
+
..Default::default()
|
|
781
|
+
},
|
|
782
|
+
),
|
|
783
|
+
);
|
|
784
|
+
|
|
785
|
+
let tasks = [
|
|
786
|
+
hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::ToTaskNum(1)),
|
|
787
|
+
{
|
|
788
|
+
// One task is super important here - as we need to look like we hit the cache
|
|
789
|
+
// to apply this query right away
|
|
790
|
+
let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::OneTask(2));
|
|
791
|
+
pr.queries = HashMap::new();
|
|
792
|
+
pr.queries.insert(
|
|
793
|
+
"the-query".to_string(),
|
|
794
|
+
WorkflowQuery {
|
|
795
|
+
query_type: "query-type".to_string(),
|
|
796
|
+
query_args: Some(b"hi".into()),
|
|
797
|
+
header: None,
|
|
798
|
+
},
|
|
799
|
+
);
|
|
800
|
+
pr
|
|
801
|
+
},
|
|
802
|
+
{
|
|
803
|
+
let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::ToTaskNum(2));
|
|
804
|
+
// Strip history, we need to look like we hit the cache for a legacy query
|
|
805
|
+
pr.history = Some(History { events: vec![] });
|
|
806
|
+
pr.query = Some(WorkflowQuery {
|
|
807
|
+
query_type: "query-type".to_string(),
|
|
808
|
+
query_args: Some(b"hi".into()),
|
|
809
|
+
header: None,
|
|
810
|
+
});
|
|
811
|
+
pr
|
|
812
|
+
},
|
|
813
|
+
];
|
|
814
|
+
let mut mock = mock_workflow_client();
|
|
815
|
+
mock.expect_respond_legacy_query()
|
|
816
|
+
.times(1)
|
|
817
|
+
.returning(move |_, _| Ok(Default::default()));
|
|
818
|
+
let mut mock = single_hist_mock_sg(wfid, t, tasks, mock, true);
|
|
819
|
+
mock.worker_cfg(|wc| wc.max_cached_workflows = 1);
|
|
820
|
+
let core = mock_worker(mock);
|
|
821
|
+
|
|
822
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
823
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
824
|
+
task.run_id,
|
|
825
|
+
vec![
|
|
826
|
+
schedule_activity_cmd(
|
|
827
|
+
1,
|
|
828
|
+
"whatever",
|
|
829
|
+
"1",
|
|
830
|
+
ActivityCancellationType::TryCancel,
|
|
831
|
+
Duration::from_secs(60),
|
|
832
|
+
Duration::from_secs(60),
|
|
833
|
+
),
|
|
834
|
+
start_timer_cmd(1, Duration::from_secs(1)),
|
|
835
|
+
],
|
|
836
|
+
))
|
|
837
|
+
.await
|
|
838
|
+
.unwrap();
|
|
839
|
+
|
|
840
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
841
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
842
|
+
task.run_id,
|
|
843
|
+
vec![
|
|
844
|
+
RequestCancelActivity { seq: 1 }.into(),
|
|
845
|
+
QueryResult {
|
|
846
|
+
query_id: "the-query".to_string(),
|
|
847
|
+
variant: Some(
|
|
848
|
+
QuerySuccess {
|
|
849
|
+
response: Some("whatever".into()),
|
|
850
|
+
}
|
|
851
|
+
.into(),
|
|
852
|
+
),
|
|
853
|
+
}
|
|
854
|
+
.into(),
|
|
855
|
+
],
|
|
856
|
+
))
|
|
857
|
+
.await
|
|
858
|
+
.unwrap();
|
|
859
|
+
|
|
860
|
+
// First should get the activity resolve
|
|
861
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
862
|
+
assert_matches!(
|
|
863
|
+
task.jobs.as_slice(),
|
|
864
|
+
[WorkflowActivationJob {
|
|
865
|
+
variant: Some(workflow_activation_job::Variant::ResolveActivity(_)),
|
|
866
|
+
}]
|
|
867
|
+
);
|
|
868
|
+
core.complete_execution(&task.run_id).await;
|
|
869
|
+
|
|
870
|
+
// Then the query
|
|
871
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
872
|
+
assert_matches!(
|
|
873
|
+
task.jobs.as_slice(),
|
|
874
|
+
[WorkflowActivationJob {
|
|
875
|
+
variant: Some(workflow_activation_job::Variant::QueryWorkflow(_)),
|
|
876
|
+
}]
|
|
877
|
+
);
|
|
878
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
879
|
+
task.run_id,
|
|
880
|
+
QueryResult {
|
|
881
|
+
query_id: LEGACY_QUERY_ID.to_string(),
|
|
882
|
+
variant: Some(
|
|
883
|
+
QuerySuccess {
|
|
884
|
+
response: Some("whatever".into()),
|
|
885
|
+
}
|
|
886
|
+
.into(),
|
|
887
|
+
),
|
|
888
|
+
}
|
|
889
|
+
.into(),
|
|
890
|
+
))
|
|
891
|
+
.await
|
|
892
|
+
.unwrap();
|
|
893
|
+
core.shutdown().await;
|
|
894
|
+
}
|
|
@@ -24,7 +24,7 @@ use tokio::sync::{watch, Barrier};
|
|
|
24
24
|
#[tokio::test]
|
|
25
25
|
async fn after_shutdown_of_worker_get_shutdown_err() {
|
|
26
26
|
let t = canned_histories::single_timer("1");
|
|
27
|
-
let worker = build_fake_worker("fake_wf_id", t,
|
|
27
|
+
let worker = build_fake_worker("fake_wf_id", t, [1]);
|
|
28
28
|
let res = worker.poll_workflow_activation().await.unwrap();
|
|
29
29
|
assert_eq!(res.jobs.len(), 1);
|
|
30
30
|
let run_id = res.run_id;
|
|
@@ -53,7 +53,7 @@ async fn after_shutdown_of_worker_get_shutdown_err() {
|
|
|
53
53
|
#[tokio::test]
|
|
54
54
|
async fn shutdown_worker_can_complete_pending_activation() {
|
|
55
55
|
let t = canned_histories::single_timer("1");
|
|
56
|
-
let worker = build_fake_worker("fake_wf_id", t,
|
|
56
|
+
let worker = build_fake_worker("fake_wf_id", t, [2]);
|
|
57
57
|
let res = worker.poll_workflow_activation().await.unwrap();
|
|
58
58
|
assert_eq!(res.jobs.len(), 1);
|
|
59
59
|
// Complete the timer, will queue PA
|
|
@@ -107,7 +107,7 @@ async fn timer_then_cancel_req_then_timer_then_cancelled() {
|
|
|
107
107
|
async fn immediate_cancel() {
|
|
108
108
|
let wfid = "fake_wf_id";
|
|
109
109
|
let t = canned_histories::immediate_wf_cancel();
|
|
110
|
-
let core = build_fake_worker(wfid, t,
|
|
110
|
+
let core = build_fake_worker(wfid, t, [1]);
|
|
111
111
|
|
|
112
112
|
poll_and_reply(
|
|
113
113
|
&core,
|
|
@@ -7,7 +7,6 @@ use crate::{
|
|
|
7
7
|
mock_worker, poll_and_reply, poll_and_reply_clears_outstanding_evicts, single_hist_mock_sg,
|
|
8
8
|
test_worker_cfg, FakeWfResponses, MockPollCfg, MocksHolder, ResponseType,
|
|
9
9
|
WorkflowCachingPolicy::{self, AfterEveryReply, NonSticky},
|
|
10
|
-
TEST_Q,
|
|
11
10
|
},
|
|
12
11
|
worker::client::mocks::{mock_manual_workflow_client, mock_workflow_client},
|
|
13
12
|
Worker,
|
|
@@ -652,7 +651,7 @@ async fn workflow_update_random_seed_on_workflow_reset() {
|
|
|
652
651
|
timer_1_id.to_string().as_str(),
|
|
653
652
|
new_run_id,
|
|
654
653
|
);
|
|
655
|
-
let core = build_fake_worker(wfid, t,
|
|
654
|
+
let core = build_fake_worker(wfid, t, [2]);
|
|
656
655
|
|
|
657
656
|
poll_and_reply(
|
|
658
657
|
&core,
|
|
@@ -706,7 +705,7 @@ async fn cancel_timer_before_sent_wf_bridge() {
|
|
|
706
705
|
t.add_full_wf_task();
|
|
707
706
|
t.add_workflow_execution_completed();
|
|
708
707
|
|
|
709
|
-
let core = build_fake_worker(wfid, t,
|
|
708
|
+
let core = build_fake_worker(wfid, t, [1]);
|
|
710
709
|
|
|
711
710
|
poll_and_reply(
|
|
712
711
|
&core,
|
|
@@ -1037,7 +1036,6 @@ async fn lots_of_workflows() {
|
|
|
1037
1036
|
let completed_count = Arc::new(Semaphore::new(0));
|
|
1038
1037
|
let killer = async {
|
|
1039
1038
|
let _ = completed_count.acquire_many(total_wfs).await.unwrap();
|
|
1040
|
-
dbg!("Shutdown initted");
|
|
1041
1039
|
worker.initiate_shutdown();
|
|
1042
1040
|
};
|
|
1043
1041
|
let poller = fanout_tasks(5, |_| {
|
|
@@ -1122,7 +1120,7 @@ async fn complete_after_eviction() {
|
|
|
1122
1120
|
let t = canned_histories::single_timer("1");
|
|
1123
1121
|
let mut mock = mock_workflow_client();
|
|
1124
1122
|
mock.expect_complete_workflow_task().times(0);
|
|
1125
|
-
let mock = single_hist_mock_sg(wfid, t,
|
|
1123
|
+
let mock = single_hist_mock_sg(wfid, t, [2], mock, true);
|
|
1126
1124
|
let core = mock_worker(mock);
|
|
1127
1125
|
|
|
1128
1126
|
let activation = core.poll_workflow_activation().await.unwrap();
|
|
@@ -1164,7 +1162,7 @@ async fn sends_appropriate_sticky_task_queue_responses() {
|
|
|
1164
1162
|
.times(1)
|
|
1165
1163
|
.returning(|_| Ok(Default::default()));
|
|
1166
1164
|
mock.expect_complete_workflow_task().times(0);
|
|
1167
|
-
let mut mock = single_hist_mock_sg(wfid, t,
|
|
1165
|
+
let mut mock = single_hist_mock_sg(wfid, t, [1], mock, false);
|
|
1168
1166
|
mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
|
|
1169
1167
|
let core = mock_worker(mock);
|
|
1170
1168
|
|
|
@@ -1182,7 +1180,7 @@ async fn sends_appropriate_sticky_task_queue_responses() {
|
|
|
1182
1180
|
async fn new_server_work_while_eviction_outstanding_doesnt_overwrite_activation() {
|
|
1183
1181
|
let wfid = "fake_wf_id";
|
|
1184
1182
|
let t = canned_histories::single_timer("1");
|
|
1185
|
-
let mock = single_hist_mock_sg(wfid, t,
|
|
1183
|
+
let mock = single_hist_mock_sg(wfid, t, [1, 2], mock_workflow_client(), false);
|
|
1186
1184
|
let taskmap = mock.outstanding_task_map.clone().unwrap();
|
|
1187
1185
|
let core = mock_worker(mock);
|
|
1188
1186
|
|
|
@@ -1224,7 +1222,7 @@ async fn buffered_work_drained_on_shutdown() {
|
|
|
1224
1222
|
t.add_workflow_task_scheduled_and_started();
|
|
1225
1223
|
// Need to build the first response before adding the timeout events b/c otherwise the history
|
|
1226
1224
|
// builder will include them in the first task
|
|
1227
|
-
let resp_1 = hist_to_poll_resp(&t, wfid.to_owned(), 1.into()
|
|
1225
|
+
let resp_1 = hist_to_poll_resp(&t, wfid.to_owned(), 1.into()).resp;
|
|
1228
1226
|
t.add_workflow_task_timed_out();
|
|
1229
1227
|
t.add_full_wf_task();
|
|
1230
1228
|
let timer_started_event_id = t.add_get_event_id(EventType::TimerStarted, None);
|
|
@@ -1242,10 +1240,7 @@ async fn buffered_work_drained_on_shutdown() {
|
|
|
1242
1240
|
// Extend the task list with the now timeout-included version of the task. We add a bunch of
|
|
1243
1241
|
// them because the poll loop will spin while new tasks are available and it is buffering them
|
|
1244
1242
|
tasks.extend(
|
|
1245
|
-
std::iter::repeat_with(||
|
|
1246
|
-
hist_to_poll_resp(&t, wfid.to_owned(), 2.into(), TEST_Q.to_string()).resp
|
|
1247
|
-
})
|
|
1248
|
-
.take(50),
|
|
1243
|
+
std::iter::repeat_with(|| hist_to_poll_resp(&t, wfid.to_owned(), 2.into()).resp).take(50),
|
|
1249
1244
|
);
|
|
1250
1245
|
let mut mock = mock_workflow_client();
|
|
1251
1246
|
mock.expect_complete_workflow_task()
|
|
@@ -1448,7 +1443,7 @@ async fn tries_cancel_of_completed_activity() {
|
|
|
1448
1443
|
t.add_workflow_task_scheduled_and_started();
|
|
1449
1444
|
|
|
1450
1445
|
let mock = mock_workflow_client();
|
|
1451
|
-
let mut mock = single_hist_mock_sg("fake_wf_id", t,
|
|
1446
|
+
let mut mock = single_hist_mock_sg("fake_wf_id", t, [1, 2], mock, true);
|
|
1452
1447
|
mock.worker_cfg(|cfg| cfg.max_cached_workflows = 1);
|
|
1453
1448
|
let core = mock_worker(mock);
|
|
1454
1449
|
|
|
@@ -1658,9 +1653,7 @@ async fn tasks_from_completion_are_delivered() {
|
|
|
1658
1653
|
|
|
1659
1654
|
let mut mock = mock_workflow_client();
|
|
1660
1655
|
let complete_resp = RespondWorkflowTaskCompletedResponse {
|
|
1661
|
-
workflow_task: Some(
|
|
1662
|
-
hist_to_poll_resp(&t, wfid.to_owned(), 2.into(), TEST_Q.to_string()).resp,
|
|
1663
|
-
),
|
|
1656
|
+
workflow_task: Some(hist_to_poll_resp(&t, wfid.to_owned(), 2.into()).resp),
|
|
1664
1657
|
activity_tasks: vec![],
|
|
1665
1658
|
};
|
|
1666
1659
|
mock.expect_complete_workflow_task()
|
|
@@ -1829,7 +1822,7 @@ async fn eviction_waits_until_replay_finished() {
|
|
|
1829
1822
|
let wfid = "fake_wf_id";
|
|
1830
1823
|
let t = canned_histories::long_sequential_timers(3);
|
|
1831
1824
|
let mock = mock_workflow_client();
|
|
1832
|
-
let mock = single_hist_mock_sg(wfid, t,
|
|
1825
|
+
let mock = single_hist_mock_sg(wfid, t, [3], mock, true);
|
|
1833
1826
|
let core = mock_worker(mock);
|
|
1834
1827
|
|
|
1835
1828
|
let activation = core.poll_workflow_activation().await.unwrap();
|
|
@@ -1890,7 +1883,7 @@ async fn autocompletes_wft_no_work() {
|
|
|
1890
1883
|
t.add_activity_task_completed(scheduled_event_id, started_event_id, Default::default());
|
|
1891
1884
|
t.add_full_wf_task();
|
|
1892
1885
|
let mock = mock_workflow_client();
|
|
1893
|
-
let mut mock = single_hist_mock_sg(wfid, t,
|
|
1886
|
+
let mut mock = single_hist_mock_sg(wfid, t, [1, 2, 3, 4], mock, true);
|
|
1894
1887
|
mock.worker_cfg(|w| w.max_cached_workflows = 1);
|
|
1895
1888
|
let core = mock_worker(mock);
|
|
1896
1889
|
|
|
@@ -1951,8 +1944,7 @@ async fn no_race_acquiring_permits() {
|
|
|
1951
1944
|
.expect_poll_workflow_task()
|
|
1952
1945
|
.returning(move |_, _| {
|
|
1953
1946
|
let t = canned_histories::single_timer("1");
|
|
1954
|
-
let poll_resp =
|
|
1955
|
-
hist_to_poll_resp(&t, wfid.to_owned(), 2.into(), TEST_Q.to_string()).resp;
|
|
1947
|
+
let poll_resp = hist_to_poll_resp(&t, wfid.to_owned(), 2.into()).resp;
|
|
1956
1948
|
async move {
|
|
1957
1949
|
task_barr.wait().await;
|
|
1958
1950
|
Ok(poll_resp.clone())
|
|
@@ -2031,13 +2023,7 @@ async fn continue_as_new_preserves_some_values() {
|
|
|
2031
2023
|
mock_client
|
|
2032
2024
|
.expect_poll_workflow_task()
|
|
2033
2025
|
.returning(move |_, _| {
|
|
2034
|
-
Ok(hist_to_poll_resp(
|
|
2035
|
-
&hist,
|
|
2036
|
-
wfid.to_owned(),
|
|
2037
|
-
ResponseType::AllHistory,
|
|
2038
|
-
TEST_Q.to_string(),
|
|
2039
|
-
)
|
|
2040
|
-
.resp)
|
|
2026
|
+
Ok(hist_to_poll_resp(&hist, wfid.to_owned(), ResponseType::AllHistory).resp)
|
|
2041
2027
|
});
|
|
2042
2028
|
mock_client
|
|
2043
2029
|
.expect_complete_workflow_task()
|
|
@@ -2068,3 +2054,36 @@ async fn continue_as_new_preserves_some_values() {
|
|
|
2068
2054
|
.await
|
|
2069
2055
|
.unwrap();
|
|
2070
2056
|
}
|
|
2057
|
+
|
|
2058
|
+
#[rstest]
|
|
2059
|
+
#[tokio::test]
|
|
2060
|
+
async fn ignorable_events_are_ok(#[values(true, false)] attribs_unset: bool) {
|
|
2061
|
+
let mut t = TestHistoryBuilder::default();
|
|
2062
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
2063
|
+
let id = t.add_get_event_id(
|
|
2064
|
+
EventType::Unspecified,
|
|
2065
|
+
Some(
|
|
2066
|
+
history_event::Attributes::WorkflowPropertiesModifiedExternallyEventAttributes(
|
|
2067
|
+
Default::default(),
|
|
2068
|
+
),
|
|
2069
|
+
),
|
|
2070
|
+
);
|
|
2071
|
+
t.modify_event(id, |e| e.worker_may_ignore = true);
|
|
2072
|
+
if attribs_unset {
|
|
2073
|
+
t.modify_event(id, |e| {
|
|
2074
|
+
e.event_type = EventType::WorkflowPropertiesModifiedExternally as i32;
|
|
2075
|
+
e.attributes = None;
|
|
2076
|
+
});
|
|
2077
|
+
}
|
|
2078
|
+
t.add_workflow_task_scheduled_and_started();
|
|
2079
|
+
|
|
2080
|
+
let mock = mock_workflow_client();
|
|
2081
|
+
let mock = single_hist_mock_sg("wheee", t, [ResponseType::AllHistory], mock, true);
|
|
2082
|
+
let core = mock_worker(mock);
|
|
2083
|
+
|
|
2084
|
+
let act = core.poll_workflow_activation().await.unwrap();
|
|
2085
|
+
assert_matches!(
|
|
2086
|
+
act.jobs[0].variant,
|
|
2087
|
+
Some(workflow_activation_job::Variant::StartWorkflow(_))
|
|
2088
|
+
);
|
|
2089
|
+
}
|