@temporalio/core-bridge 1.6.0 → 1.7.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 +520 -456
- package/lib/index.d.ts +8 -6
- package/lib/index.js.map +1 -1
- package/package.json +8 -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 +2 -2
- package/sdk-core/.buildkite/docker/docker-compose.yaml +1 -1
- package/sdk-core/.buildkite/pipeline.yml +1 -1
- package/sdk-core/.github/workflows/heavy.yml +1 -0
- package/sdk-core/README.md +13 -7
- package/sdk-core/client/src/lib.rs +27 -9
- package/sdk-core/client/src/metrics.rs +17 -8
- package/sdk-core/client/src/raw.rs +3 -3
- package/sdk-core/core/Cargo.toml +3 -4
- package/sdk-core/core/src/abstractions/take_cell.rs +28 -0
- package/sdk-core/core/src/abstractions.rs +197 -18
- package/sdk-core/core/src/core_tests/activity_tasks.rs +137 -45
- package/sdk-core/core/src/core_tests/child_workflows.rs +6 -5
- package/sdk-core/core/src/core_tests/determinism.rs +212 -2
- package/sdk-core/core/src/core_tests/local_activities.rs +183 -36
- package/sdk-core/core/src/core_tests/queries.rs +32 -14
- package/sdk-core/core/src/core_tests/workers.rs +8 -5
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +340 -51
- package/sdk-core/core/src/ephemeral_server/mod.rs +110 -8
- package/sdk-core/core/src/internal_flags.rs +141 -0
- package/sdk-core/core/src/lib.rs +14 -9
- package/sdk-core/core/src/replay/mod.rs +16 -27
- package/sdk-core/core/src/telemetry/metrics.rs +69 -35
- package/sdk-core/core/src/telemetry/mod.rs +38 -14
- package/sdk-core/core/src/telemetry/prometheus_server.rs +19 -13
- package/sdk-core/core/src/test_help/mod.rs +65 -13
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +119 -160
- package/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +89 -0
- package/sdk-core/core/src/worker/activities/local_activities.rs +122 -6
- package/sdk-core/core/src/worker/activities.rs +347 -173
- package/sdk-core/core/src/worker/client/mocks.rs +22 -2
- package/sdk-core/core/src/worker/client.rs +18 -2
- package/sdk-core/core/src/worker/mod.rs +137 -44
- package/sdk-core/core/src/worker/workflow/history_update.rs +132 -51
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +207 -166
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +6 -7
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +6 -7
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +157 -82
- package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +12 -12
- package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +6 -7
- package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +13 -15
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +170 -60
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +24 -16
- package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +6 -8
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +320 -204
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +10 -13
- package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +15 -23
- package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +187 -46
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +237 -111
- package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +13 -13
- package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +10 -6
- package/sdk-core/core/src/worker/workflow/managed_run.rs +81 -62
- package/sdk-core/core/src/worker/workflow/mod.rs +341 -79
- package/sdk-core/core/src/worker/workflow/run_cache.rs +18 -11
- package/sdk-core/core/src/worker/workflow/wft_extraction.rs +15 -3
- package/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +2 -0
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +75 -52
- package/sdk-core/core-api/Cargo.toml +0 -1
- package/sdk-core/core-api/src/lib.rs +13 -7
- package/sdk-core/core-api/src/telemetry.rs +4 -6
- package/sdk-core/core-api/src/worker.rs +5 -0
- package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +80 -55
- package/sdk-core/fsm/rustfsm_trait/src/lib.rs +22 -68
- package/sdk-core/histories/ends_empty_wft_complete.bin +0 -0
- package/sdk-core/histories/old_change_marker_format.bin +0 -0
- package/sdk-core/protos/api_upstream/.github/CODEOWNERS +2 -1
- package/sdk-core/protos/api_upstream/Makefile +1 -1
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +5 -17
- package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +11 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +1 -6
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +6 -6
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +5 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +22 -6
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +48 -19
- package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +2 -0
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +3 -0
- package/sdk-core/protos/api_upstream/temporal/api/{enums/v1/interaction_type.proto → protocol/v1/message.proto} +29 -11
- package/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +63 -0
- package/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +111 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +59 -28
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +2 -2
- package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +7 -8
- package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +10 -7
- package/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +19 -30
- package/sdk-core/protos/local/temporal/sdk/core/common/common.proto +1 -0
- package/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +1 -0
- package/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +8 -0
- package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +65 -60
- package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +85 -84
- package/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +9 -3
- package/sdk-core/sdk/Cargo.toml +1 -1
- package/sdk-core/sdk/src/lib.rs +21 -5
- package/sdk-core/sdk/src/workflow_context/options.rs +7 -1
- package/sdk-core/sdk/src/workflow_context.rs +24 -17
- package/sdk-core/sdk/src/workflow_future.rs +9 -3
- package/sdk-core/sdk-core-protos/src/history_builder.rs +114 -89
- package/sdk-core/sdk-core-protos/src/history_info.rs +6 -1
- package/sdk-core/sdk-core-protos/src/lib.rs +205 -64
- package/sdk-core/test-utils/src/canned_histories.rs +106 -296
- package/sdk-core/test-utils/src/lib.rs +32 -5
- package/sdk-core/tests/heavy_tests.rs +10 -43
- package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +25 -3
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +5 -3
- package/sdk-core/tests/integ_tests/metrics_tests.rs +218 -16
- package/sdk-core/tests/integ_tests/polling_tests.rs +3 -8
- package/sdk-core/tests/integ_tests/queries_tests.rs +4 -2
- package/sdk-core/tests/integ_tests/visibility_tests.rs +34 -23
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +97 -81
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -0
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -0
- package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +80 -3
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +5 -1
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +1 -0
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +25 -3
- package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +2 -4
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +30 -0
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +64 -0
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -0
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +4 -0
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +3 -1
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +7 -2
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +6 -7
- package/sdk-core/tests/integ_tests/workflow_tests.rs +8 -8
- package/sdk-core/tests/main.rs +16 -25
- package/sdk-core/tests/runner.rs +11 -9
- package/src/conversions.rs +14 -8
- package/src/runtime.rs +9 -8
- package/ts/index.ts +8 -6
- package/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +0 -87
|
@@ -2,7 +2,7 @@ use crate::{
|
|
|
2
2
|
prost_dur,
|
|
3
3
|
test_help::{
|
|
4
4
|
build_fake_worker, build_mock_pollers, canned_histories, mock_manual_poller, mock_worker,
|
|
5
|
-
MockPollCfg, MockWorkerInputs, MocksHolder, ResponseType,
|
|
5
|
+
MockPollCfg, MockWorkerInputs, MocksHolder, ResponseType, WorkerExt,
|
|
6
6
|
},
|
|
7
7
|
worker::client::mocks::mock_workflow_client,
|
|
8
8
|
PollActivityError, PollWfError,
|
|
@@ -144,13 +144,18 @@ async fn can_shutdown_local_act_only_worker_when_act_polling() {
|
|
|
144
144
|
.await
|
|
145
145
|
.unwrap();
|
|
146
146
|
barrier.wait().await;
|
|
147
|
+
// We need to see workflow poll return shutdown before activity poll will
|
|
148
|
+
assert_matches!(
|
|
149
|
+
worker.poll_workflow_activation().await.unwrap_err(),
|
|
150
|
+
PollWfError::ShutDown
|
|
151
|
+
);
|
|
147
152
|
assert_matches!(
|
|
148
153
|
worker.poll_activity_task().await.unwrap_err(),
|
|
149
154
|
PollActivityError::ShutDown
|
|
150
155
|
);
|
|
151
156
|
}
|
|
152
157
|
);
|
|
153
|
-
worker.
|
|
158
|
+
worker.drain_pollers_and_shutdown().await;
|
|
154
159
|
}
|
|
155
160
|
|
|
156
161
|
#[tokio::test]
|
|
@@ -190,9 +195,7 @@ async fn complete_with_task_not_found_during_shutdown() {
|
|
|
190
195
|
complete_order.borrow_mut().push(1);
|
|
191
196
|
};
|
|
192
197
|
tokio::join!(shutdown_fut, poll_fut, complete_fut);
|
|
193
|
-
|
|
194
|
-
// workflow task is marked complete as soon as we get not found back from the server.
|
|
195
|
-
assert_eq!(&complete_order.into_inner(), &[1, 3, 2])
|
|
198
|
+
assert_eq!(&complete_order.into_inner(), &[1, 2, 3])
|
|
196
199
|
}
|
|
197
200
|
|
|
198
201
|
#[tokio::test]
|
|
@@ -16,11 +16,12 @@ use rstest::{fixture, rstest};
|
|
|
16
16
|
use std::{
|
|
17
17
|
collections::{HashMap, VecDeque},
|
|
18
18
|
sync::{
|
|
19
|
-
atomic::{AtomicU64, Ordering},
|
|
19
|
+
atomic::{AtomicBool, AtomicU64, Ordering},
|
|
20
20
|
Arc,
|
|
21
21
|
},
|
|
22
22
|
time::Duration,
|
|
23
23
|
};
|
|
24
|
+
use temporal_client::WorkflowOptions;
|
|
24
25
|
use temporal_sdk::{ActivityOptions, CancellableFuture, WfContext};
|
|
25
26
|
use temporal_sdk_core_api::{errors::PollWfError, Worker as WorkerTrait};
|
|
26
27
|
use temporal_sdk_core_protos::{
|
|
@@ -33,24 +34,29 @@ use temporal_sdk_core_protos::{
|
|
|
33
34
|
workflow_commands::{
|
|
34
35
|
ActivityCancellationType, CancelTimer, CompleteWorkflowExecution,
|
|
35
36
|
ContinueAsNewWorkflowExecution, FailWorkflowExecution, RequestCancelActivity,
|
|
36
|
-
ScheduleActivity,
|
|
37
|
+
ScheduleActivity, SetPatchMarker,
|
|
37
38
|
},
|
|
38
39
|
workflow_completion::WorkflowActivationCompletion,
|
|
39
40
|
},
|
|
40
|
-
default_wes_attribs,
|
|
41
|
+
default_act_sched, default_wes_attribs,
|
|
41
42
|
temporal::api::{
|
|
42
43
|
command::v1::command::Attributes,
|
|
43
44
|
common::v1::{Payload, RetryPolicy},
|
|
44
45
|
enums::v1::{EventType, WorkflowTaskFailedCause},
|
|
45
46
|
failure::v1::Failure,
|
|
46
|
-
history::v1::{
|
|
47
|
+
history::v1::{
|
|
48
|
+
history_event, TimerFiredEventAttributes,
|
|
49
|
+
WorkflowPropertiesModifiedExternallyEventAttributes,
|
|
50
|
+
},
|
|
47
51
|
workflowservice::v1::{
|
|
48
52
|
GetWorkflowExecutionHistoryResponse, RespondWorkflowTaskCompletedResponse,
|
|
49
53
|
},
|
|
50
54
|
},
|
|
51
|
-
DEFAULT_WORKFLOW_TYPE,
|
|
55
|
+
DEFAULT_ACTIVITY_TYPE, DEFAULT_WORKFLOW_TYPE,
|
|
56
|
+
};
|
|
57
|
+
use temporal_sdk_core_test_utils::{
|
|
58
|
+
fanout_tasks, schedule_activity_cmd, start_timer_cmd, WorkerTestHelpers,
|
|
52
59
|
};
|
|
53
|
-
use temporal_sdk_core_test_utils::{fanout_tasks, start_timer_cmd};
|
|
54
60
|
use tokio::{
|
|
55
61
|
join,
|
|
56
62
|
sync::{Barrier, Semaphore},
|
|
@@ -120,7 +126,7 @@ async fn single_activity_completion(worker: Worker) {
|
|
|
120
126
|
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
121
127
|
vec![ScheduleActivity {
|
|
122
128
|
activity_id: "fake_activity".to_string(),
|
|
123
|
-
..
|
|
129
|
+
..default_act_sched()
|
|
124
130
|
}
|
|
125
131
|
.into()],
|
|
126
132
|
),
|
|
@@ -245,7 +251,7 @@ async fn scheduled_activity_cancellation_try_cancel(hist_batches: &'static [usiz
|
|
|
245
251
|
seq: activity_seq,
|
|
246
252
|
activity_id: activity_id.to_string(),
|
|
247
253
|
cancellation_type: ActivityCancellationType::TryCancel as i32,
|
|
248
|
-
..
|
|
254
|
+
..default_act_sched()
|
|
249
255
|
}
|
|
250
256
|
.into()],
|
|
251
257
|
),
|
|
@@ -281,7 +287,7 @@ async fn scheduled_activity_timeout(hist_batches: &'static [usize]) {
|
|
|
281
287
|
vec![ScheduleActivity {
|
|
282
288
|
seq: activity_seq,
|
|
283
289
|
activity_id: activity_id.to_string(),
|
|
284
|
-
..
|
|
290
|
+
..default_act_sched()
|
|
285
291
|
}
|
|
286
292
|
.into()],
|
|
287
293
|
),
|
|
@@ -334,7 +340,7 @@ async fn started_activity_timeout(hist_batches: &'static [usize]) {
|
|
|
334
340
|
vec![ScheduleActivity {
|
|
335
341
|
seq: activity_seq,
|
|
336
342
|
activity_id: activity_seq.to_string(),
|
|
337
|
-
..
|
|
343
|
+
..default_act_sched()
|
|
338
344
|
}
|
|
339
345
|
.into()],
|
|
340
346
|
),
|
|
@@ -389,7 +395,7 @@ async fn cancelled_activity_timeout(hist_batches: &'static [usize]) {
|
|
|
389
395
|
vec![ScheduleActivity {
|
|
390
396
|
seq: activity_seq,
|
|
391
397
|
activity_id: activity_id.to_string(),
|
|
392
|
-
..
|
|
398
|
+
..default_act_sched()
|
|
393
399
|
}
|
|
394
400
|
.into()],
|
|
395
401
|
),
|
|
@@ -457,10 +463,10 @@ async fn abandoned_activities_ignore_start_and_complete(hist_batches: &'static [
|
|
|
457
463
|
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
458
464
|
t.add_full_wf_task();
|
|
459
465
|
let act_scheduled_event_id = t.add_activity_task_scheduled(activity_id);
|
|
460
|
-
let timer_started_event_id = t.
|
|
466
|
+
let timer_started_event_id = t.add_by_type(EventType::TimerStarted);
|
|
461
467
|
t.add_timer_fired(timer_started_event_id, "1".to_string());
|
|
462
468
|
t.add_full_wf_task();
|
|
463
|
-
let timer_started_event_id = t.
|
|
469
|
+
let timer_started_event_id = t.add_by_type(EventType::TimerStarted);
|
|
464
470
|
let act_started_event_id = t.add_activity_task_started(act_scheduled_event_id);
|
|
465
471
|
t.add_activity_task_completed(
|
|
466
472
|
act_scheduled_event_id,
|
|
@@ -476,7 +482,7 @@ async fn abandoned_activities_ignore_start_and_complete(hist_batches: &'static [
|
|
|
476
482
|
|
|
477
483
|
worker.register_wf(wf_type.to_owned(), |ctx: WfContext| async move {
|
|
478
484
|
let act_fut = ctx.activity(ActivityOptions {
|
|
479
|
-
activity_type:
|
|
485
|
+
activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
|
|
480
486
|
start_to_close_timeout: Some(Duration::from_secs(5)),
|
|
481
487
|
cancellation_type: ActivityCancellationType::Abandon,
|
|
482
488
|
..Default::default()
|
|
@@ -542,7 +548,7 @@ async fn verify_activity_cancellation(
|
|
|
542
548
|
seq: activity_seq,
|
|
543
549
|
activity_id: activity_seq.to_string(),
|
|
544
550
|
cancellation_type: cancel_type as i32,
|
|
545
|
-
..
|
|
551
|
+
..default_act_sched()
|
|
546
552
|
}
|
|
547
553
|
.into()],
|
|
548
554
|
),
|
|
@@ -610,7 +616,7 @@ async fn verify_activity_cancellation_wait_for_cancellation(activity_id: u32, wo
|
|
|
610
616
|
seq: activity_id,
|
|
611
617
|
activity_id: activity_id.to_string(),
|
|
612
618
|
cancellation_type: ActivityCancellationType::WaitCancellationCompleted as i32,
|
|
613
|
-
..
|
|
619
|
+
..default_act_sched()
|
|
614
620
|
}
|
|
615
621
|
.into()],
|
|
616
622
|
),
|
|
@@ -947,7 +953,7 @@ async fn activity_not_canceled_on_replay_repro(hist_batches: &'static [usize]) {
|
|
|
947
953
|
seq: activity_id,
|
|
948
954
|
activity_id: activity_id.to_string(),
|
|
949
955
|
cancellation_type: ActivityCancellationType::TryCancel as i32,
|
|
950
|
-
..
|
|
956
|
+
..default_act_sched()
|
|
951
957
|
}
|
|
952
958
|
.into(),
|
|
953
959
|
start_timer_cmd(1, Duration::from_secs(1)),
|
|
@@ -989,9 +995,9 @@ async fn activity_not_canceled_when_also_completed_repro(hist_batches: &'static
|
|
|
989
995
|
&job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
990
996
|
vec![ScheduleActivity {
|
|
991
997
|
seq: activity_id,
|
|
992
|
-
activity_id:
|
|
998
|
+
activity_id: "act-1".to_string(),
|
|
993
999
|
cancellation_type: ActivityCancellationType::TryCancel as i32,
|
|
994
|
-
..
|
|
1000
|
+
..default_act_sched()
|
|
995
1001
|
}
|
|
996
1002
|
.into()],
|
|
997
1003
|
),
|
|
@@ -1092,7 +1098,7 @@ async fn wft_timeout_repro(hist_batches: &'static [usize]) {
|
|
|
1092
1098
|
seq: activity_id,
|
|
1093
1099
|
activity_id: activity_id.to_string(),
|
|
1094
1100
|
cancellation_type: ActivityCancellationType::TryCancel as i32,
|
|
1095
|
-
..
|
|
1101
|
+
..default_act_sched()
|
|
1096
1102
|
}
|
|
1097
1103
|
.into()],
|
|
1098
1104
|
),
|
|
@@ -1225,14 +1231,13 @@ async fn buffered_work_drained_on_shutdown() {
|
|
|
1225
1231
|
let resp_1 = hist_to_poll_resp(&t, wfid.to_owned(), 1.into()).resp;
|
|
1226
1232
|
t.add_workflow_task_timed_out();
|
|
1227
1233
|
t.add_full_wf_task();
|
|
1228
|
-
let timer_started_event_id = t.
|
|
1229
|
-
t.add(
|
|
1230
|
-
|
|
1231
|
-
history_event::Attributes::TimerFiredEventAttributes(TimerFiredEventAttributes {
|
|
1234
|
+
let timer_started_event_id = t.add_by_type(EventType::TimerStarted);
|
|
1235
|
+
t.add(history_event::Attributes::TimerFiredEventAttributes(
|
|
1236
|
+
TimerFiredEventAttributes {
|
|
1232
1237
|
started_event_id: timer_started_event_id,
|
|
1233
1238
|
timer_id: "1".to_string(),
|
|
1234
|
-
}
|
|
1235
|
-
);
|
|
1239
|
+
},
|
|
1240
|
+
));
|
|
1236
1241
|
t.add_full_wf_task();
|
|
1237
1242
|
t.add_workflow_execution_completed();
|
|
1238
1243
|
|
|
@@ -1264,6 +1269,8 @@ async fn buffered_work_drained_on_shutdown() {
|
|
|
1264
1269
|
.unwrap();
|
|
1265
1270
|
};
|
|
1266
1271
|
let complete_first = async move {
|
|
1272
|
+
// If the first complete is sent too fast, we may not have had a chance to buffer work.
|
|
1273
|
+
tokio::time::sleep(Duration::from_millis(50)).await;
|
|
1267
1274
|
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
1268
1275
|
act1.run_id,
|
|
1269
1276
|
start_timer_cmd(1, Duration::from_secs(1)),
|
|
@@ -1272,8 +1279,6 @@ async fn buffered_work_drained_on_shutdown() {
|
|
|
1272
1279
|
.unwrap();
|
|
1273
1280
|
};
|
|
1274
1281
|
join!(poll_fut, complete_first, async {
|
|
1275
|
-
// If the shutdown is sent too too fast, we might not have got a chance to even buffer work
|
|
1276
|
-
tokio::time::sleep(Duration::from_millis(5)).await;
|
|
1277
1282
|
core.shutdown().await;
|
|
1278
1283
|
});
|
|
1279
1284
|
}
|
|
@@ -1303,7 +1308,7 @@ async fn fail_wft_then_recover() {
|
|
|
1303
1308
|
act.run_id.clone(),
|
|
1304
1309
|
vec![ScheduleActivity {
|
|
1305
1310
|
activity_id: "fake_activity".to_string(),
|
|
1306
|
-
..
|
|
1311
|
+
..default_act_sched()
|
|
1307
1312
|
}
|
|
1308
1313
|
.into()],
|
|
1309
1314
|
))
|
|
@@ -1355,12 +1360,17 @@ async fn poll_response_triggers_wf_error() {
|
|
|
1355
1360
|
t.add_full_wf_task();
|
|
1356
1361
|
t.add_workflow_execution_completed();
|
|
1357
1362
|
|
|
1358
|
-
let mh = MockPollCfg::from_resp_batches(
|
|
1363
|
+
let mut mh = MockPollCfg::from_resp_batches(
|
|
1359
1364
|
"fake_wf_id",
|
|
1360
1365
|
t,
|
|
1361
1366
|
[ResponseType::AllHistory],
|
|
1362
1367
|
mock_workflow_client(),
|
|
1363
1368
|
);
|
|
1369
|
+
// Fail wft will be called when auto-failing.
|
|
1370
|
+
mh.num_expected_fails = 1;
|
|
1371
|
+
mh.expect_fail_wft_matcher = Box::new(move |_, cause, _| {
|
|
1372
|
+
matches!(cause, WorkflowTaskFailedCause::NonDeterministicError)
|
|
1373
|
+
});
|
|
1364
1374
|
let mock = build_mock_pollers(mh);
|
|
1365
1375
|
let core = mock_worker(mock);
|
|
1366
1376
|
// Poll for first WFT, which is immediately an eviction
|
|
@@ -1453,7 +1463,7 @@ async fn tries_cancel_of_completed_activity() {
|
|
|
1453
1463
|
ScheduleActivity {
|
|
1454
1464
|
seq: 1,
|
|
1455
1465
|
activity_id: "1".to_string(),
|
|
1456
|
-
..
|
|
1466
|
+
..default_act_sched()
|
|
1457
1467
|
}
|
|
1458
1468
|
.into(),
|
|
1459
1469
|
))
|
|
@@ -1953,7 +1963,7 @@ async fn autocompletes_wft_no_work() {
|
|
|
1953
1963
|
seq: 1,
|
|
1954
1964
|
activity_id: activity_id.to_string(),
|
|
1955
1965
|
cancellation_type: ActivityCancellationType::Abandon as i32,
|
|
1956
|
-
..
|
|
1966
|
+
..default_act_sched()
|
|
1957
1967
|
}
|
|
1958
1968
|
.into(),
|
|
1959
1969
|
))
|
|
@@ -2066,10 +2076,7 @@ async fn continue_as_new_preserves_some_values() {
|
|
|
2066
2076
|
let mut mock_client = mock_workflow_client();
|
|
2067
2077
|
let hist = {
|
|
2068
2078
|
let mut t = TestHistoryBuilder::default();
|
|
2069
|
-
t.add(
|
|
2070
|
-
EventType::WorkflowExecutionStarted,
|
|
2071
|
-
wes_attrs.clone().into(),
|
|
2072
|
-
);
|
|
2079
|
+
t.add(wes_attrs.clone());
|
|
2073
2080
|
t.add_full_wf_task();
|
|
2074
2081
|
t
|
|
2075
2082
|
};
|
|
@@ -2113,21 +2120,19 @@ async fn continue_as_new_preserves_some_values() {
|
|
|
2113
2120
|
async fn ignorable_events_are_ok(#[values(true, false)] attribs_unset: bool) {
|
|
2114
2121
|
let mut t = TestHistoryBuilder::default();
|
|
2115
2122
|
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
2116
|
-
let id = t.
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
t.modify_event(id, |e| e.worker_may_ignore = true);
|
|
2125
|
-
if attribs_unset {
|
|
2126
|
-
t.modify_event(id, |e| {
|
|
2127
|
-
e.event_type = EventType::WorkflowPropertiesModifiedExternally as i32;
|
|
2123
|
+
let id = t.add(WorkflowPropertiesModifiedExternallyEventAttributes::default());
|
|
2124
|
+
t.modify_event(id, |e| {
|
|
2125
|
+
e.worker_may_ignore = true;
|
|
2126
|
+
// Ignorable events are ignored if we can't interpret the proto of either the event attribs
|
|
2127
|
+
// or proto - otherwise (this is the _may_ part of may ignore), we'll still try to process
|
|
2128
|
+
// it. That processing may ultimately still choose to do nothing, if we want to _explicitly_
|
|
2129
|
+
// ignore it.
|
|
2130
|
+
if attribs_unset {
|
|
2128
2131
|
e.attributes = None;
|
|
2129
|
-
}
|
|
2130
|
-
|
|
2132
|
+
} else {
|
|
2133
|
+
e.event_type = EventType::Unspecified as i32;
|
|
2134
|
+
}
|
|
2135
|
+
});
|
|
2131
2136
|
t.add_workflow_task_scheduled_and_started();
|
|
2132
2137
|
|
|
2133
2138
|
let mock = mock_workflow_client();
|
|
@@ -2165,7 +2170,7 @@ async fn fetching_to_continue_replay_works() {
|
|
|
2165
2170
|
// next page happen.
|
|
2166
2171
|
fetch_resp.next_page_token = vec![2];
|
|
2167
2172
|
|
|
2168
|
-
let timer_started_event_id = t.
|
|
2173
|
+
let timer_started_event_id = t.add_by_type(EventType::TimerStarted);
|
|
2169
2174
|
t.add_timer_fired(timer_started_event_id, "1".to_string());
|
|
2170
2175
|
t.add_full_wf_task();
|
|
2171
2176
|
let mut final_fetch_resp: GetWorkflowExecutionHistoryResponse =
|
|
@@ -2331,3 +2336,287 @@ async fn ensure_fetching_fail_during_complete_sends_task_failure() {
|
|
|
2331
2336
|
|
|
2332
2337
|
core.shutdown().await;
|
|
2333
2338
|
}
|
|
2339
|
+
|
|
2340
|
+
#[tokio::test]
|
|
2341
|
+
async fn lang_internal_flags() {
|
|
2342
|
+
let mut t = TestHistoryBuilder::default();
|
|
2343
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
2344
|
+
t.add_full_wf_task();
|
|
2345
|
+
t.set_flags_first_wft(&[], &[1]);
|
|
2346
|
+
t.add_we_signaled("sig1", vec![]);
|
|
2347
|
+
t.add_full_wf_task();
|
|
2348
|
+
t.set_flags_last_wft(&[], &[2]);
|
|
2349
|
+
t.add_we_signaled("sig2", vec![]);
|
|
2350
|
+
t.add_full_wf_task();
|
|
2351
|
+
t.add_workflow_execution_completed();
|
|
2352
|
+
|
|
2353
|
+
let mut mh = MockPollCfg::from_resp_batches(
|
|
2354
|
+
"fake_wf_id",
|
|
2355
|
+
t,
|
|
2356
|
+
[ResponseType::ToTaskNum(2), ResponseType::AllHistory],
|
|
2357
|
+
mock_workflow_client(),
|
|
2358
|
+
);
|
|
2359
|
+
mh.completion_asserts = Some(Box::new(|c| {
|
|
2360
|
+
assert_matches!(c.sdk_metadata.lang_used_flags.as_slice(), &[2]);
|
|
2361
|
+
}));
|
|
2362
|
+
let mut mock = build_mock_pollers(mh);
|
|
2363
|
+
mock.worker_cfg(|wc| wc.max_cached_workflows = 1);
|
|
2364
|
+
let core = mock_worker(mock);
|
|
2365
|
+
|
|
2366
|
+
let act = core.poll_workflow_activation().await.unwrap();
|
|
2367
|
+
assert_matches!(act.available_internal_flags.as_slice(), [1]);
|
|
2368
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::empty(act.run_id))
|
|
2369
|
+
.await
|
|
2370
|
+
.unwrap();
|
|
2371
|
+
|
|
2372
|
+
let act = core.poll_workflow_activation().await.unwrap();
|
|
2373
|
+
let mut completion = WorkflowActivationCompletion::empty(act.run_id);
|
|
2374
|
+
completion.add_internal_flags(2);
|
|
2375
|
+
core.complete_workflow_activation(completion).await.unwrap();
|
|
2376
|
+
|
|
2377
|
+
let act = core.poll_workflow_activation().await.unwrap();
|
|
2378
|
+
assert_matches!(act.available_internal_flags.as_slice(), [1, 2]);
|
|
2379
|
+
core.complete_execution(&act.run_id).await;
|
|
2380
|
+
core.shutdown().await;
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
// Verify we send flags to server when they're used
|
|
2384
|
+
#[tokio::test]
|
|
2385
|
+
async fn core_internal_flags() {
|
|
2386
|
+
let mut t = TestHistoryBuilder::default();
|
|
2387
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
2388
|
+
t.add_full_wf_task();
|
|
2389
|
+
let act_scheduled_event_id = t.add_activity_task_scheduled("act-id");
|
|
2390
|
+
let act_started_event_id = t.add_activity_task_started(act_scheduled_event_id);
|
|
2391
|
+
t.add_activity_task_completed(
|
|
2392
|
+
act_scheduled_event_id,
|
|
2393
|
+
act_started_event_id,
|
|
2394
|
+
Default::default(),
|
|
2395
|
+
);
|
|
2396
|
+
t.add_full_wf_task();
|
|
2397
|
+
t.add_workflow_execution_completed();
|
|
2398
|
+
|
|
2399
|
+
let mut mh = MockPollCfg::from_resp_batches(
|
|
2400
|
+
"fake_wf_id",
|
|
2401
|
+
t,
|
|
2402
|
+
[ResponseType::ToTaskNum(1), ResponseType::ToTaskNum(2)],
|
|
2403
|
+
mock_workflow_client(),
|
|
2404
|
+
);
|
|
2405
|
+
let first_poll = AtomicBool::new(true);
|
|
2406
|
+
mh.completion_asserts = Some(Box::new(move |c| {
|
|
2407
|
+
if !first_poll.load(Ordering::Acquire) {
|
|
2408
|
+
assert_matches!(c.sdk_metadata.core_used_flags.as_slice(), &[1]);
|
|
2409
|
+
}
|
|
2410
|
+
first_poll.store(false, Ordering::Release);
|
|
2411
|
+
}));
|
|
2412
|
+
let mut mock = build_mock_pollers(mh);
|
|
2413
|
+
mock.worker_cfg(|wc| wc.max_cached_workflows = 1);
|
|
2414
|
+
let core = mock_worker(mock);
|
|
2415
|
+
|
|
2416
|
+
let act = core.poll_workflow_activation().await.unwrap();
|
|
2417
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
2418
|
+
act.run_id,
|
|
2419
|
+
schedule_activity_cmd(
|
|
2420
|
+
1,
|
|
2421
|
+
"whatever",
|
|
2422
|
+
"act-id",
|
|
2423
|
+
ActivityCancellationType::TryCancel,
|
|
2424
|
+
Duration::from_secs(60),
|
|
2425
|
+
Duration::from_secs(60),
|
|
2426
|
+
),
|
|
2427
|
+
))
|
|
2428
|
+
.await
|
|
2429
|
+
.unwrap();
|
|
2430
|
+
|
|
2431
|
+
let act = core.poll_workflow_activation().await.unwrap();
|
|
2432
|
+
core.complete_execution(&act.run_id).await;
|
|
2433
|
+
core.shutdown().await;
|
|
2434
|
+
}
|
|
2435
|
+
|
|
2436
|
+
#[tokio::test]
|
|
2437
|
+
async fn post_terminal_commands_are_discarded() {
|
|
2438
|
+
let mut t = TestHistoryBuilder::default();
|
|
2439
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
2440
|
+
t.add_full_wf_task();
|
|
2441
|
+
t.add_workflow_execution_completed();
|
|
2442
|
+
|
|
2443
|
+
let mut mh = MockPollCfg::from_resp_batches(
|
|
2444
|
+
"fake_wf_id",
|
|
2445
|
+
t,
|
|
2446
|
+
[ResponseType::ToTaskNum(1), ResponseType::AllHistory],
|
|
2447
|
+
mock_workflow_client(),
|
|
2448
|
+
);
|
|
2449
|
+
mh.completion_asserts = Some(Box::new(|c| {
|
|
2450
|
+
// Only the complete execution command should actually be sent
|
|
2451
|
+
assert_eq!(c.commands.len(), 1);
|
|
2452
|
+
}));
|
|
2453
|
+
let mut mock = build_mock_pollers(mh);
|
|
2454
|
+
mock.worker_cfg(|wc| wc.max_cached_workflows = 1);
|
|
2455
|
+
let core = mock_worker(mock);
|
|
2456
|
+
|
|
2457
|
+
let act = core.poll_workflow_activation().await.unwrap();
|
|
2458
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
2459
|
+
act.run_id,
|
|
2460
|
+
vec![
|
|
2461
|
+
CompleteWorkflowExecution { result: None }.into(),
|
|
2462
|
+
start_timer_cmd(1, Duration::from_secs(1)),
|
|
2463
|
+
],
|
|
2464
|
+
))
|
|
2465
|
+
.await
|
|
2466
|
+
.unwrap();
|
|
2467
|
+
|
|
2468
|
+
// This just ensures applying the complete history w/ the completion command works, though
|
|
2469
|
+
// there's no activation.
|
|
2470
|
+
let act = core.poll_workflow_activation().await;
|
|
2471
|
+
assert_matches!(act.unwrap_err(), PollWfError::ShutDown);
|
|
2472
|
+
|
|
2473
|
+
core.shutdown().await;
|
|
2474
|
+
}
|
|
2475
|
+
|
|
2476
|
+
// Lang expects to always see jobs in this order:
|
|
2477
|
+
// patches, signals, everything else, queries
|
|
2478
|
+
#[tokio::test]
|
|
2479
|
+
async fn jobs_are_in_appropriate_order() {
|
|
2480
|
+
let p1 = "patchy-mc-patchface";
|
|
2481
|
+
let p2 = "enchi-the-kitty";
|
|
2482
|
+
let mut t = TestHistoryBuilder::default();
|
|
2483
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
2484
|
+
t.add_full_wf_task();
|
|
2485
|
+
t.add_has_change_marker(p1, false);
|
|
2486
|
+
let timer_started_event_id = t.add_by_type(EventType::TimerStarted);
|
|
2487
|
+
t.add_timer_fired(timer_started_event_id, "1".to_string());
|
|
2488
|
+
t.add_we_signaled("yummy-salmon", vec![]);
|
|
2489
|
+
t.add_full_wf_task();
|
|
2490
|
+
t.add_has_change_marker(p2, false);
|
|
2491
|
+
t.add_workflow_execution_completed();
|
|
2492
|
+
|
|
2493
|
+
let mh = MockPollCfg::from_resp_batches(
|
|
2494
|
+
"fake_wf_id",
|
|
2495
|
+
t,
|
|
2496
|
+
[ResponseType::AllHistory],
|
|
2497
|
+
mock_workflow_client(),
|
|
2498
|
+
);
|
|
2499
|
+
let mut mock = build_mock_pollers(mh);
|
|
2500
|
+
mock.worker_cfg(|wc| wc.max_cached_workflows = 1);
|
|
2501
|
+
let core = mock_worker(mock);
|
|
2502
|
+
|
|
2503
|
+
let act = core.poll_workflow_activation().await.unwrap();
|
|
2504
|
+
// Patch notifications always come first
|
|
2505
|
+
assert_matches!(
|
|
2506
|
+
act.jobs[0].variant.as_ref().unwrap(),
|
|
2507
|
+
workflow_activation_job::Variant::NotifyHasPatch(_)
|
|
2508
|
+
);
|
|
2509
|
+
assert_matches!(
|
|
2510
|
+
act.jobs[1].variant.as_ref().unwrap(),
|
|
2511
|
+
workflow_activation_job::Variant::StartWorkflow(_)
|
|
2512
|
+
);
|
|
2513
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
2514
|
+
act.run_id,
|
|
2515
|
+
vec![
|
|
2516
|
+
SetPatchMarker {
|
|
2517
|
+
patch_id: p1.to_string(),
|
|
2518
|
+
deprecated: false,
|
|
2519
|
+
}
|
|
2520
|
+
.into(),
|
|
2521
|
+
start_timer_cmd(1, Duration::from_secs(1)),
|
|
2522
|
+
],
|
|
2523
|
+
))
|
|
2524
|
+
.await
|
|
2525
|
+
.unwrap();
|
|
2526
|
+
let act = core.poll_workflow_activation().await.unwrap();
|
|
2527
|
+
assert_matches!(
|
|
2528
|
+
act.jobs[0].variant.as_ref().unwrap(),
|
|
2529
|
+
workflow_activation_job::Variant::NotifyHasPatch(_)
|
|
2530
|
+
);
|
|
2531
|
+
assert_matches!(
|
|
2532
|
+
act.jobs[1].variant.as_ref().unwrap(),
|
|
2533
|
+
workflow_activation_job::Variant::SignalWorkflow(_)
|
|
2534
|
+
);
|
|
2535
|
+
assert_matches!(
|
|
2536
|
+
act.jobs[2].variant.as_ref().unwrap(),
|
|
2537
|
+
workflow_activation_job::Variant::FireTimer(_)
|
|
2538
|
+
);
|
|
2539
|
+
}
|
|
2540
|
+
|
|
2541
|
+
#[rstest]
|
|
2542
|
+
#[tokio::test]
|
|
2543
|
+
async fn history_length_with_fail_and_timeout(
|
|
2544
|
+
#[values(true, false)] use_cache: bool,
|
|
2545
|
+
#[values(1, 2, 3)] history_responses_case: u8,
|
|
2546
|
+
) {
|
|
2547
|
+
let wfid = "fake_wf_id";
|
|
2548
|
+
let mut t = TestHistoryBuilder::default();
|
|
2549
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
2550
|
+
t.add_full_wf_task();
|
|
2551
|
+
let timer_started_event_id = t.add_by_type(EventType::TimerStarted);
|
|
2552
|
+
t.add_timer_fired(timer_started_event_id, "1".to_string());
|
|
2553
|
+
t.add_workflow_task_scheduled_and_started();
|
|
2554
|
+
t.add_workflow_task_failed_with_failure(WorkflowTaskFailedCause::Unspecified, "ahh".into());
|
|
2555
|
+
t.add_workflow_task_scheduled_and_started();
|
|
2556
|
+
t.add_workflow_task_timed_out();
|
|
2557
|
+
t.add_full_wf_task();
|
|
2558
|
+
let timer_started_event_id = t.add_by_type(EventType::TimerStarted);
|
|
2559
|
+
t.add_timer_fired(timer_started_event_id, "2".to_string());
|
|
2560
|
+
t.add_full_wf_task();
|
|
2561
|
+
t.add_workflow_execution_completed();
|
|
2562
|
+
|
|
2563
|
+
let mut mock_client = mock_workflow_client();
|
|
2564
|
+
let history_responses = match history_responses_case {
|
|
2565
|
+
1 => vec![ResponseType::AllHistory],
|
|
2566
|
+
2 => vec![
|
|
2567
|
+
ResponseType::ToTaskNum(1),
|
|
2568
|
+
ResponseType::ToTaskNum(2),
|
|
2569
|
+
ResponseType::AllHistory,
|
|
2570
|
+
],
|
|
2571
|
+
3 => {
|
|
2572
|
+
let mut needs_fetch = hist_to_poll_resp(&t, wfid, ResponseType::ToTaskNum(2)).resp;
|
|
2573
|
+
needs_fetch.next_page_token = vec![1];
|
|
2574
|
+
// Truncate the history a bit in order to force incomplete WFT
|
|
2575
|
+
needs_fetch.history.as_mut().unwrap().events.truncate(6);
|
|
2576
|
+
let needs_fetch_resp = ResponseType::Raw(needs_fetch);
|
|
2577
|
+
let mut empty_fetch_resp: GetWorkflowExecutionHistoryResponse =
|
|
2578
|
+
t.get_history_info(1).unwrap().into();
|
|
2579
|
+
empty_fetch_resp.history.as_mut().unwrap().events = vec![];
|
|
2580
|
+
mock_client
|
|
2581
|
+
.expect_get_workflow_execution_history()
|
|
2582
|
+
.returning(move |_, _, _| Ok(empty_fetch_resp.clone()))
|
|
2583
|
+
.times(1);
|
|
2584
|
+
vec![
|
|
2585
|
+
ResponseType::ToTaskNum(1),
|
|
2586
|
+
needs_fetch_resp,
|
|
2587
|
+
ResponseType::ToTaskNum(2),
|
|
2588
|
+
ResponseType::AllHistory,
|
|
2589
|
+
]
|
|
2590
|
+
}
|
|
2591
|
+
_ => unreachable!(),
|
|
2592
|
+
};
|
|
2593
|
+
|
|
2594
|
+
let mut mh = MockPollCfg::from_resp_batches(wfid, t, history_responses, mock_client);
|
|
2595
|
+
if history_responses_case == 3 {
|
|
2596
|
+
// Expect the failed pagination fetch
|
|
2597
|
+
mh.num_expected_fails = 1;
|
|
2598
|
+
}
|
|
2599
|
+
let mut worker = mock_sdk_cfg(mh, |wc| {
|
|
2600
|
+
if use_cache {
|
|
2601
|
+
wc.max_cached_workflows = 1;
|
|
2602
|
+
}
|
|
2603
|
+
});
|
|
2604
|
+
worker.register_wf(DEFAULT_WORKFLOW_TYPE, |ctx: WfContext| async move {
|
|
2605
|
+
assert_eq!(ctx.history_length(), 3);
|
|
2606
|
+
ctx.timer(Duration::from_secs(1)).await;
|
|
2607
|
+
assert_eq!(ctx.history_length(), 14);
|
|
2608
|
+
ctx.timer(Duration::from_secs(1)).await;
|
|
2609
|
+
assert_eq!(ctx.history_length(), 19);
|
|
2610
|
+
Ok(().into())
|
|
2611
|
+
});
|
|
2612
|
+
worker
|
|
2613
|
+
.submit_wf(
|
|
2614
|
+
wfid.to_owned(),
|
|
2615
|
+
DEFAULT_WORKFLOW_TYPE.to_owned(),
|
|
2616
|
+
vec![],
|
|
2617
|
+
WorkflowOptions::default(),
|
|
2618
|
+
)
|
|
2619
|
+
.await
|
|
2620
|
+
.unwrap();
|
|
2621
|
+
worker.run_until_done().await.unwrap();
|
|
2622
|
+
}
|