@temporalio/core-bridge 0.23.0 → 1.0.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 +118 -15
- package/Cargo.toml +2 -1
- package/LICENSE.md +1 -1
- package/README.md +1 -1
- package/index.d.ts +47 -18
- package/package.json +7 -7
- 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/docker-compose.yaml +4 -2
- package/sdk-core/ARCHITECTURE.md +9 -7
- package/sdk-core/README.md +5 -1
- package/sdk-core/arch_docs/diagrams/workflow_internals.svg +1 -0
- package/sdk-core/bridge-ffi/src/wrappers.rs +0 -3
- package/sdk-core/client/src/lib.rs +26 -8
- package/sdk-core/client/src/raw.rs +166 -54
- package/sdk-core/client/src/retry.rs +9 -4
- package/sdk-core/client/src/workflow_handle/mod.rs +4 -2
- package/sdk-core/core/Cargo.toml +2 -0
- package/sdk-core/core/src/abstractions.rs +137 -16
- package/sdk-core/core/src/core_tests/activity_tasks.rs +258 -63
- package/sdk-core/core/src/core_tests/child_workflows.rs +1 -2
- package/sdk-core/core/src/core_tests/determinism.rs +2 -2
- package/sdk-core/core/src/core_tests/local_activities.rs +8 -7
- package/sdk-core/core/src/core_tests/queries.rs +146 -60
- package/sdk-core/core/src/core_tests/replay_flag.rs +1 -1
- package/sdk-core/core/src/core_tests/workers.rs +39 -23
- package/sdk-core/core/src/core_tests/workflow_cancels.rs +1 -1
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +387 -280
- package/sdk-core/core/src/lib.rs +6 -4
- package/sdk-core/core/src/pollers/poll_buffer.rs +16 -10
- package/sdk-core/core/src/protosext/mod.rs +6 -6
- package/sdk-core/core/src/retry_logic.rs +1 -1
- package/sdk-core/core/src/telemetry/metrics.rs +21 -7
- package/sdk-core/core/src/telemetry/mod.rs +18 -4
- package/sdk-core/core/src/test_help/mod.rs +341 -109
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +18 -9
- package/sdk-core/core/src/worker/activities/local_activities.rs +19 -16
- package/sdk-core/core/src/worker/activities.rs +156 -29
- package/sdk-core/core/src/worker/client.rs +1 -0
- package/sdk-core/core/src/worker/mod.rs +132 -659
- package/sdk-core/core/src/{workflow → worker/workflow}/bridge.rs +1 -1
- package/sdk-core/core/src/{workflow → worker/workflow}/driven_workflow.rs +1 -1
- package/sdk-core/core/src/{workflow → worker/workflow}/history_update.rs +16 -2
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/activity_state_machine.rs +39 -4
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/cancel_external_state_machine.rs +5 -2
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/cancel_workflow_state_machine.rs +1 -1
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/child_workflow_state_machine.rs +2 -4
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/complete_workflow_state_machine.rs +0 -0
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/continue_as_new_workflow_state_machine.rs +1 -1
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/fail_workflow_state_machine.rs +0 -0
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/local_activity_state_machine.rs +2 -5
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/mod.rs +1 -1
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/mutable_side_effect_state_machine.rs +0 -0
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/patch_state_machine.rs +1 -1
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/side_effect_state_machine.rs +0 -0
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/signal_external_state_machine.rs +4 -2
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/timer_state_machine.rs +1 -2
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/transition_coverage.rs +1 -1
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/upsert_search_attributes_state_machine.rs +5 -7
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/workflow_machines/local_acts.rs +2 -2
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/workflow_machines.rs +40 -16
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/workflow_task_state_machine.rs +0 -0
- package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +198 -0
- package/sdk-core/core/src/worker/workflow/managed_run.rs +627 -0
- package/sdk-core/core/src/worker/workflow/mod.rs +1115 -0
- package/sdk-core/core/src/worker/workflow/run_cache.rs +143 -0
- package/sdk-core/core/src/worker/workflow/wft_poller.rs +88 -0
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +936 -0
- package/sdk-core/core-api/src/errors.rs +3 -10
- package/sdk-core/core-api/src/lib.rs +2 -1
- package/sdk-core/core-api/src/worker.rs +26 -2
- package/sdk-core/etc/dynamic-config.yaml +2 -0
- package/sdk-core/integ-with-otel.sh +1 -1
- package/sdk-core/protos/api_upstream/Makefile +4 -4
- package/sdk-core/protos/api_upstream/api-linter.yaml +2 -0
- package/sdk-core/protos/api_upstream/buf.yaml +8 -9
- package/sdk-core/protos/api_upstream/temporal/api/cluster/v1/message.proto +83 -0
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +7 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/cluster.proto +40 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +3 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +3 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +60 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +3 -0
- package/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +32 -4
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +69 -19
- package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +13 -0
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +163 -0
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +97 -0
- package/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +300 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +25 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +180 -3
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +53 -3
- package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +2 -2
- package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +6 -5
- package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +0 -1
- package/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +2 -1
- package/sdk-core/protos/local/temporal/sdk/core/common/common.proto +0 -64
- package/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +2 -1
- package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +11 -8
- package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +30 -25
- package/sdk-core/sdk/src/activity_context.rs +12 -5
- package/sdk-core/sdk/src/app_data.rs +37 -0
- package/sdk-core/sdk/src/lib.rs +76 -43
- package/sdk-core/sdk/src/workflow_context/options.rs +8 -6
- package/sdk-core/sdk/src/workflow_context.rs +14 -19
- package/sdk-core/sdk/src/workflow_future.rs +11 -6
- package/sdk-core/sdk-core-protos/src/history_builder.rs +19 -5
- package/sdk-core/sdk-core-protos/src/history_info.rs +11 -6
- package/sdk-core/sdk-core-protos/src/lib.rs +74 -176
- package/sdk-core/test-utils/src/lib.rs +85 -72
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +11 -9
- package/sdk-core/tests/integ_tests/polling_tests.rs +12 -0
- package/sdk-core/tests/integ_tests/queries_tests.rs +39 -22
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +49 -4
- package/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +61 -0
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +74 -13
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +19 -0
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +6 -3
- package/sdk-core/tests/integ_tests/workflow_tests.rs +10 -23
- package/sdk-core/tests/load_tests.rs +8 -3
- package/sdk-core/tests/main.rs +2 -1
- package/src/conversions.rs +47 -39
- package/src/errors.rs +10 -21
- package/src/lib.rs +342 -325
- package/sdk-core/core/src/pending_activations.rs +0 -173
- package/sdk-core/core/src/worker/wft_delivery.rs +0 -81
- package/sdk-core/core/src/workflow/mod.rs +0 -478
- package/sdk-core/core/src/workflow/workflow_tasks/cache_manager.rs +0 -194
- package/sdk-core/core/src/workflow/workflow_tasks/concurrency_manager.rs +0 -418
- package/sdk-core/core/src/workflow/workflow_tasks/mod.rs +0 -989
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
use crate::{
|
|
2
2
|
test_help::{
|
|
3
|
-
canned_histories, hist_to_poll_resp, mock_worker,
|
|
3
|
+
build_mock_pollers, canned_histories, hist_to_poll_resp, mock_worker, single_hist_mock_sg,
|
|
4
|
+
MockPollCfg, ResponseType, TEST_Q,
|
|
4
5
|
},
|
|
5
|
-
worker::client::mocks::mock_workflow_client,
|
|
6
|
+
worker::{client::mocks::mock_workflow_client, LEGACY_QUERY_ID},
|
|
6
7
|
};
|
|
7
8
|
use std::{
|
|
8
9
|
collections::{HashMap, VecDeque},
|
|
@@ -26,8 +27,7 @@ use temporal_sdk_core_protos::{
|
|
|
26
27
|
history::v1::History,
|
|
27
28
|
query::v1::WorkflowQuery,
|
|
28
29
|
workflowservice::v1::{
|
|
29
|
-
GetWorkflowExecutionHistoryResponse,
|
|
30
|
-
RespondWorkflowTaskCompletedResponse,
|
|
30
|
+
GetWorkflowExecutionHistoryResponse, RespondWorkflowTaskCompletedResponse,
|
|
31
31
|
},
|
|
32
32
|
},
|
|
33
33
|
};
|
|
@@ -43,7 +43,7 @@ async fn legacy_query(#[case] include_history: bool) {
|
|
|
43
43
|
let t = canned_histories::single_timer("1");
|
|
44
44
|
let mut header = HashMap::new();
|
|
45
45
|
header.insert("head".to_string(), Payload::from(b"er"));
|
|
46
|
-
let tasks =
|
|
46
|
+
let tasks = [
|
|
47
47
|
hist_to_poll_resp(&t, wfid.to_owned(), 1.into(), TEST_Q.to_string()),
|
|
48
48
|
{
|
|
49
49
|
let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), 1.into(), TEST_Q.to_string());
|
|
@@ -58,17 +58,10 @@ async fn legacy_query(#[case] include_history: bool) {
|
|
|
58
58
|
pr
|
|
59
59
|
},
|
|
60
60
|
hist_to_poll_resp(&t, wfid.to_owned(), 2.into(), TEST_Q.to_string()),
|
|
61
|
-
]
|
|
62
|
-
let mut
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
.returning(|_| Ok(RespondWorkflowTaskCompletedResponse::default()));
|
|
66
|
-
mock_client
|
|
67
|
-
.expect_respond_legacy_query()
|
|
68
|
-
.times(1)
|
|
69
|
-
.returning(move |_, _| Ok(RespondQueryTaskCompletedResponse::default()));
|
|
70
|
-
|
|
71
|
-
let mut mock = MocksHolder::from_client_with_responses(mock_client, tasks, vec![]);
|
|
61
|
+
];
|
|
62
|
+
let mut mock = MockPollCfg::from_resp_batches(wfid, t, tasks, mock_workflow_client());
|
|
63
|
+
mock.num_expected_legacy_query_resps = 1;
|
|
64
|
+
let mut mock = build_mock_pollers(mock);
|
|
72
65
|
if !include_history {
|
|
73
66
|
mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
|
|
74
67
|
}
|
|
@@ -186,12 +179,8 @@ async fn new_queries(#[case] num_queries: usize) {
|
|
|
186
179
|
},
|
|
187
180
|
]);
|
|
188
181
|
let mut mock_client = mock_workflow_client();
|
|
189
|
-
mock_client
|
|
190
|
-
.expect_complete_workflow_task()
|
|
191
|
-
.returning(|_| Ok(RespondWorkflowTaskCompletedResponse::default()));
|
|
192
182
|
mock_client.expect_respond_legacy_query().times(0);
|
|
193
|
-
|
|
194
|
-
let mut mock = MocksHolder::from_client_with_responses(mock_client, tasks, vec![]);
|
|
183
|
+
let mut mock = single_hist_mock_sg(wfid, t, tasks, mock_client, true);
|
|
195
184
|
mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
|
|
196
185
|
let core = mock_worker(mock);
|
|
197
186
|
|
|
@@ -260,18 +249,10 @@ async fn legacy_query_failure_on_wft_failure() {
|
|
|
260
249
|
pr.history = Some(History { events: vec![] });
|
|
261
250
|
pr
|
|
262
251
|
},
|
|
263
|
-
hist_to_poll_resp(&t, wfid.to_owned(), 2.into(), TEST_Q.to_string()),
|
|
264
252
|
]);
|
|
265
|
-
let mut
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
.returning(|_| Ok(RespondWorkflowTaskCompletedResponse::default()));
|
|
269
|
-
mock_client
|
|
270
|
-
.expect_respond_legacy_query()
|
|
271
|
-
.times(1)
|
|
272
|
-
.returning(move |_, _| Ok(RespondQueryTaskCompletedResponse::default()));
|
|
273
|
-
|
|
274
|
-
let mut mock = MocksHolder::from_client_with_responses(mock_client, tasks, vec![]);
|
|
253
|
+
let mut mock = MockPollCfg::from_resp_batches(wfid, t, tasks, mock_workflow_client());
|
|
254
|
+
mock.num_expected_legacy_query_resps = 1;
|
|
255
|
+
let mut mock = build_mock_pollers(mock);
|
|
275
256
|
mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
|
|
276
257
|
let core = mock_worker(mock);
|
|
277
258
|
|
|
@@ -305,6 +286,64 @@ async fn legacy_query_failure_on_wft_failure() {
|
|
|
305
286
|
core.shutdown().await;
|
|
306
287
|
}
|
|
307
288
|
|
|
289
|
+
#[rstest::rstest]
|
|
290
|
+
#[tokio::test]
|
|
291
|
+
async fn query_failure_because_nondeterminism(#[values(true, false)] legacy: bool) {
|
|
292
|
+
let wfid = "fake_wf_id";
|
|
293
|
+
let t = canned_histories::single_timer("1");
|
|
294
|
+
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
|
+
);
|
|
301
|
+
if legacy {
|
|
302
|
+
pr.query = Some(WorkflowQuery {
|
|
303
|
+
query_type: "query-type".to_string(),
|
|
304
|
+
query_args: Some(b"hi".into()),
|
|
305
|
+
header: None,
|
|
306
|
+
});
|
|
307
|
+
} else {
|
|
308
|
+
pr.queries = HashMap::new();
|
|
309
|
+
pr.queries.insert(
|
|
310
|
+
"q1".to_string(),
|
|
311
|
+
WorkflowQuery {
|
|
312
|
+
query_type: "query-type".to_string(),
|
|
313
|
+
query_args: Some(b"hi".into()),
|
|
314
|
+
header: None,
|
|
315
|
+
},
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
pr
|
|
319
|
+
}];
|
|
320
|
+
let mut mock = MockPollCfg::from_resp_batches(wfid, t, tasks, mock_workflow_client());
|
|
321
|
+
if legacy {
|
|
322
|
+
mock.num_expected_legacy_query_resps = 1;
|
|
323
|
+
} else {
|
|
324
|
+
mock.num_expected_fails = 1;
|
|
325
|
+
}
|
|
326
|
+
let mut mock = build_mock_pollers(mock);
|
|
327
|
+
mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
|
|
328
|
+
let core = mock_worker(mock);
|
|
329
|
+
|
|
330
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
331
|
+
// Nondeterminism, should result in WFT/query being failed
|
|
332
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::empty(task.run_id))
|
|
333
|
+
.await
|
|
334
|
+
.unwrap();
|
|
335
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
336
|
+
assert_matches!(
|
|
337
|
+
task.jobs[0].variant,
|
|
338
|
+
Some(workflow_activation_job::Variant::RemoveFromCache(_))
|
|
339
|
+
);
|
|
340
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::empty(task.run_id))
|
|
341
|
+
.await
|
|
342
|
+
.unwrap();
|
|
343
|
+
|
|
344
|
+
core.shutdown().await;
|
|
345
|
+
}
|
|
346
|
+
|
|
308
347
|
#[rstest::rstest]
|
|
309
348
|
#[tokio::test]
|
|
310
349
|
async fn legacy_query_after_complete(#[values(false, true)] full_history: bool) {
|
|
@@ -328,28 +367,29 @@ async fn legacy_query_after_complete(#[values(false, true)] full_history: bool)
|
|
|
328
367
|
query_args: Some(b"hi".into()),
|
|
329
368
|
header: None,
|
|
330
369
|
});
|
|
331
|
-
pr
|
|
370
|
+
pr.resp
|
|
332
371
|
};
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
.returning(move |_, _| Ok(RespondQueryTaskCompletedResponse::default()));
|
|
372
|
+
// Server would never send us a workflow task *without* a query that goes all the way to
|
|
373
|
+
// execution completed. So, don't do that. It messes with the mock unlocking the next
|
|
374
|
+
// task since we (appropriately) won't respond to server in that situation.
|
|
375
|
+
let mut tasks = if full_history {
|
|
376
|
+
vec![]
|
|
377
|
+
} 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
|
+
]
|
|
387
|
+
};
|
|
388
|
+
tasks.extend([query_with_hist_task.clone(), query_with_hist_task]);
|
|
351
389
|
|
|
352
|
-
let mut mock =
|
|
390
|
+
let mut mock = MockPollCfg::from_resp_batches(wfid, t, tasks, mock_workflow_client());
|
|
391
|
+
mock.num_expected_legacy_query_resps = 2;
|
|
392
|
+
let mut mock = build_mock_pollers(mock);
|
|
353
393
|
mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
|
|
354
394
|
let core = mock_worker(mock);
|
|
355
395
|
|
|
@@ -474,7 +514,7 @@ async fn query_cache_miss_causes_page_fetch_dont_reply_wft_too_early(
|
|
|
474
514
|
Ok(RespondWorkflowTaskCompletedResponse::default())
|
|
475
515
|
});
|
|
476
516
|
|
|
477
|
-
let mut mock =
|
|
517
|
+
let mut mock = single_hist_mock_sg(wfid, t, tasks, mock_client, true);
|
|
478
518
|
mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
|
|
479
519
|
let core = mock_worker(mock);
|
|
480
520
|
let task = core.poll_workflow_activation().await.unwrap();
|
|
@@ -568,7 +608,7 @@ async fn query_replay_with_continue_as_new_doesnt_reply_empty_command() {
|
|
|
568
608
|
Ok(RespondWorkflowTaskCompletedResponse::default())
|
|
569
609
|
});
|
|
570
610
|
|
|
571
|
-
let mut mock =
|
|
611
|
+
let mut mock = single_hist_mock_sg(wfid, t, tasks, mock_client, true);
|
|
572
612
|
mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
|
|
573
613
|
let core = mock_worker(mock);
|
|
574
614
|
|
|
@@ -634,17 +674,63 @@ async fn query_replay_with_continue_as_new_doesnt_reply_empty_command() {
|
|
|
634
674
|
.await
|
|
635
675
|
.unwrap();
|
|
636
676
|
|
|
637
|
-
|
|
677
|
+
core.shutdown().await;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
#[tokio::test]
|
|
681
|
+
async fn legacy_query_response_gets_not_found_not_fatal() {
|
|
682
|
+
let wfid = "fake_wf_id";
|
|
683
|
+
let t = canned_histories::single_timer("1");
|
|
684
|
+
let tasks = [{
|
|
685
|
+
let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), 1.into(), TEST_Q.to_string());
|
|
686
|
+
pr.query = Some(WorkflowQuery {
|
|
687
|
+
query_type: "query-type".to_string(),
|
|
688
|
+
query_args: Some(b"hi".into()),
|
|
689
|
+
header: None,
|
|
690
|
+
});
|
|
691
|
+
pr
|
|
692
|
+
}];
|
|
693
|
+
let mut mock = mock_workflow_client();
|
|
694
|
+
mock.expect_respond_legacy_query()
|
|
695
|
+
.times(1)
|
|
696
|
+
.returning(move |_, _| Err(tonic::Status::not_found("Query gone boi")));
|
|
697
|
+
let mock = MockPollCfg::from_resp_batches(wfid, t, tasks, mock);
|
|
698
|
+
let mut mock = build_mock_pollers(mock);
|
|
699
|
+
mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
|
|
700
|
+
let core = mock_worker(mock);
|
|
701
|
+
|
|
638
702
|
let task = core.poll_workflow_activation().await.unwrap();
|
|
703
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
704
|
+
task.run_id,
|
|
705
|
+
start_timer_cmd(1, Duration::from_secs(1)),
|
|
706
|
+
))
|
|
707
|
+
.await
|
|
708
|
+
.unwrap();
|
|
709
|
+
|
|
710
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
711
|
+
// Poll again, and we end up getting a `query` field query response
|
|
639
712
|
assert_matches!(
|
|
640
713
|
task.jobs.as_slice(),
|
|
641
714
|
[WorkflowActivationJob {
|
|
642
|
-
variant: Some(workflow_activation_job::Variant::
|
|
643
|
-
}]
|
|
715
|
+
variant: Some(workflow_activation_job::Variant::QueryWorkflow(q)),
|
|
716
|
+
}] => q
|
|
644
717
|
);
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
.
|
|
718
|
+
// Fail wft which should result in query being failed
|
|
719
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
720
|
+
task.run_id,
|
|
721
|
+
QueryResult {
|
|
722
|
+
query_id: LEGACY_QUERY_ID.to_string(),
|
|
723
|
+
variant: Some(
|
|
724
|
+
QuerySuccess {
|
|
725
|
+
response: Some("hi".into()),
|
|
726
|
+
}
|
|
727
|
+
.into(),
|
|
728
|
+
),
|
|
729
|
+
}
|
|
730
|
+
.into(),
|
|
731
|
+
))
|
|
732
|
+
.await
|
|
733
|
+
.unwrap();
|
|
648
734
|
|
|
649
735
|
core.shutdown().await;
|
|
650
736
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
use crate::{
|
|
2
2
|
test_help::{
|
|
3
3
|
build_fake_worker, build_mock_pollers, canned_histories, mock_manual_poller, mock_worker,
|
|
4
|
-
MockPollCfg,
|
|
4
|
+
MockPollCfg, MockWorkerInputs, MocksHolder,
|
|
5
5
|
},
|
|
6
6
|
worker::client::mocks::mock_workflow_client,
|
|
7
7
|
PollActivityError, PollWfError,
|
|
@@ -40,16 +40,8 @@ async fn after_shutdown_of_worker_get_shutdown_err() {
|
|
|
40
40
|
))
|
|
41
41
|
.await
|
|
42
42
|
.unwrap();
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
assert_matches!(
|
|
46
|
-
res.jobs[0].variant,
|
|
47
|
-
Some(workflow_activation_job::Variant::RemoveFromCache(_))
|
|
48
|
-
);
|
|
49
|
-
worker
|
|
50
|
-
.complete_workflow_activation(WorkflowActivationCompletion::empty(run_id.clone()))
|
|
51
|
-
.await
|
|
52
|
-
.unwrap();
|
|
43
|
+
|
|
44
|
+
// Shutdown proceeds if the only outstanding activations are evictions
|
|
53
45
|
assert_matches!(
|
|
54
46
|
worker.poll_workflow_activation().await.unwrap_err(),
|
|
55
47
|
PollWfError::ShutDown
|
|
@@ -83,9 +75,7 @@ async fn shutdown_worker_can_complete_pending_activation() {
|
|
|
83
75
|
))
|
|
84
76
|
.await
|
|
85
77
|
.unwrap();
|
|
86
|
-
//
|
|
87
|
-
worker.poll_workflow_activation().await.unwrap();
|
|
88
|
-
// Now it's shut down
|
|
78
|
+
// Shutdown proceeds if the only outstanding activations are evictions
|
|
89
79
|
assert_matches!(
|
|
90
80
|
worker.poll_workflow_activation().await.unwrap_err(),
|
|
91
81
|
PollWfError::ShutDown
|
|
@@ -109,7 +99,7 @@ async fn worker_shutdown_during_poll_doesnt_deadlock() {
|
|
|
109
99
|
}
|
|
110
100
|
.boxed()
|
|
111
101
|
});
|
|
112
|
-
let mw =
|
|
102
|
+
let mw = MockWorkerInputs::new_from_poller(Box::new(mock_poller));
|
|
113
103
|
let mut mock_client = mock_workflow_client();
|
|
114
104
|
mock_client
|
|
115
105
|
.expect_complete_workflow_task()
|
|
@@ -182,16 +172,11 @@ async fn complete_with_task_not_found_during_shutdown() {
|
|
|
182
172
|
complete_order.borrow_mut().push(3);
|
|
183
173
|
};
|
|
184
174
|
let poll_fut = async {
|
|
185
|
-
// This
|
|
186
|
-
// goes through, at which point it will return the eviction.
|
|
187
|
-
let res = core.poll_workflow_activation().await.unwrap();
|
|
175
|
+
// This will return shutdown once the completion goes through
|
|
188
176
|
assert_matches!(
|
|
189
|
-
|
|
190
|
-
|
|
177
|
+
core.poll_workflow_activation().await.unwrap_err(),
|
|
178
|
+
PollWfError::ShutDown
|
|
191
179
|
);
|
|
192
|
-
core.complete_workflow_activation(WorkflowActivationCompletion::empty(res.run_id))
|
|
193
|
-
.await
|
|
194
|
-
.unwrap();
|
|
195
180
|
complete_order.borrow_mut().push(2);
|
|
196
181
|
};
|
|
197
182
|
let complete_fut = async {
|
|
@@ -208,3 +193,34 @@ async fn complete_with_task_not_found_during_shutdown() {
|
|
|
208
193
|
// workflow task is marked complete as soon as we get not found back from the server.
|
|
209
194
|
assert_eq!(&complete_order.into_inner(), &[1, 3, 2])
|
|
210
195
|
}
|
|
196
|
+
|
|
197
|
+
#[tokio::test]
|
|
198
|
+
async fn complete_eviction_after_shutdown_doesnt_panic() {
|
|
199
|
+
let t = canned_histories::single_timer("1");
|
|
200
|
+
let mut mh = build_mock_pollers(MockPollCfg::from_resp_batches(
|
|
201
|
+
"fakeid",
|
|
202
|
+
t,
|
|
203
|
+
[1],
|
|
204
|
+
mock_workflow_client(),
|
|
205
|
+
));
|
|
206
|
+
mh.make_wft_stream_interminable();
|
|
207
|
+
let core = mock_worker(mh);
|
|
208
|
+
|
|
209
|
+
let res = core.poll_workflow_activation().await.unwrap();
|
|
210
|
+
assert_eq!(res.jobs.len(), 1);
|
|
211
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
212
|
+
res.run_id,
|
|
213
|
+
vec![start_timer_cmd(1, Duration::from_secs(1))],
|
|
214
|
+
))
|
|
215
|
+
.await
|
|
216
|
+
.unwrap();
|
|
217
|
+
let res = core.poll_workflow_activation().await.unwrap();
|
|
218
|
+
assert_matches!(
|
|
219
|
+
res.jobs[0].variant,
|
|
220
|
+
Some(workflow_activation_job::Variant::RemoveFromCache(_))
|
|
221
|
+
);
|
|
222
|
+
core.shutdown().await;
|
|
223
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::empty(res.run_id))
|
|
224
|
+
.await
|
|
225
|
+
.unwrap();
|
|
226
|
+
}
|
|
@@ -2,8 +2,8 @@ use crate::{
|
|
|
2
2
|
job_assert,
|
|
3
3
|
test_help::{
|
|
4
4
|
build_fake_worker, canned_histories, gen_assert_and_reply, poll_and_reply, ResponseType,
|
|
5
|
+
WorkflowCachingPolicy::NonSticky,
|
|
5
6
|
},
|
|
6
|
-
workflow::WorkflowCachingPolicy::NonSticky,
|
|
7
7
|
};
|
|
8
8
|
use rstest::rstest;
|
|
9
9
|
use std::time::Duration;
|