@temporalio/core-bridge 1.14.2-canary-release-testing.0 → 1.16.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 +794 -650
- package/bridge-macros/src/derive_tryintojs.rs +40 -0
- package/lib/native.d.ts +24 -3
- package/package.json +4 -4
- 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/.github/workflows/per-pr.yml +6 -6
- package/sdk-core/AGENTS.md +42 -31
- package/sdk-core/Cargo.toml +4 -1
- package/sdk-core/README.md +19 -13
- package/sdk-core/crates/client/Cargo.toml +4 -0
- package/sdk-core/crates/client/README.md +139 -0
- package/sdk-core/crates/client/src/async_activity_handle.rs +297 -0
- package/sdk-core/crates/client/src/callback_based.rs +7 -0
- package/sdk-core/crates/client/src/errors.rs +294 -0
- package/sdk-core/crates/client/src/{raw.rs → grpc.rs} +370 -159
- package/sdk-core/crates/client/src/lib.rs +920 -1326
- package/sdk-core/crates/client/src/metrics.rs +24 -33
- package/sdk-core/crates/client/src/options_structs.rs +457 -0
- package/sdk-core/crates/client/src/replaceable.rs +5 -4
- package/sdk-core/crates/client/src/request_extensions.rs +8 -9
- package/sdk-core/crates/client/src/retry.rs +99 -54
- package/sdk-core/crates/client/src/{worker/mod.rs → worker.rs} +104 -29
- package/sdk-core/crates/client/src/workflow_handle.rs +826 -0
- package/sdk-core/crates/common/Cargo.toml +62 -3
- package/sdk-core/crates/common/build.rs +742 -12
- package/sdk-core/crates/common/protos/api_upstream/.github/workflows/ci.yml +2 -0
- package/sdk-core/crates/common/protos/api_upstream/.github/workflows/create-release.yml +0 -5
- package/sdk-core/crates/common/protos/api_upstream/Makefile +2 -1
- package/sdk-core/crates/common/protos/api_upstream/README.md +8 -0
- package/sdk-core/crates/common/protos/api_upstream/cmd/check-path-conflicts/main.go +137 -0
- package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv2.json +3329 -2647
- package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv3.yaml +2734 -708
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/activity/v1/message.proto +155 -3
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/command/v1/message.proto +26 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/common/v1/message.proto +8 -1
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/deployment/v1/message.proto +27 -1
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/activity.proto +81 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/event_type.proto +4 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +4 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +15 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/workflow.proto +63 -15
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/errordetails/v1/message.proto +8 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/failure/v1/message.proto +1 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/history/v1/message.proto +111 -17
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/namespace/v1/message.proto +21 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/nexus/v1/message.proto +20 -1
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +4 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/schedule/v1/message.proto +2 -2
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/worker/v1/message.proto +4 -7
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflow/v1/message.proto +80 -22
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +347 -23
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +242 -43
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/core_interface.proto +15 -0
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/nexus/nexus.proto +9 -2
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +8 -0
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +22 -5
- package/sdk-core/crates/common/src/activity_definition.rs +20 -0
- package/sdk-core/crates/common/src/data_converters.rs +770 -0
- package/sdk-core/crates/common/src/envconfig.rs +5 -0
- package/sdk-core/crates/common/src/lib.rs +15 -211
- package/sdk-core/crates/common/src/payload_visitor.rs +648 -0
- package/sdk-core/crates/common/src/priority.rs +110 -0
- package/sdk-core/crates/common/src/protos/canned_histories.rs +19 -0
- package/sdk-core/crates/common/src/protos/history_builder.rs +45 -0
- package/sdk-core/crates/common/src/protos/history_info.rs +2 -0
- package/sdk-core/crates/common/src/protos/mod.rs +134 -27
- package/sdk-core/crates/common/src/protos/task_token.rs +3 -3
- package/sdk-core/crates/common/src/protos/utilities.rs +11 -0
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/log_export.rs +11 -16
- package/sdk-core/crates/common/src/telemetry/metrics/core.rs +125 -0
- package/sdk-core/crates/common/src/telemetry/metrics.rs +272 -225
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/otel.rs +8 -13
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_meter.rs +49 -50
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_server.rs +2 -3
- package/sdk-core/crates/common/src/telemetry.rs +278 -19
- package/sdk-core/crates/common/src/worker.rs +68 -636
- package/sdk-core/crates/common/src/workflow_definition.rs +60 -0
- package/sdk-core/crates/macros/Cargo.toml +5 -1
- package/sdk-core/crates/macros/src/activities_definitions.rs +585 -0
- package/sdk-core/crates/macros/src/fsm_impl.rs +507 -0
- package/sdk-core/crates/macros/src/lib.rs +138 -512
- package/sdk-core/crates/macros/src/macro_utils.rs +106 -0
- package/sdk-core/crates/macros/src/workflow_definitions.rs +1224 -0
- package/sdk-core/crates/sdk/Cargo.toml +19 -6
- package/sdk-core/crates/sdk/README.md +415 -0
- package/sdk-core/crates/sdk/src/activities.rs +417 -0
- package/sdk-core/crates/sdk/src/interceptors.rs +1 -1
- package/sdk-core/crates/sdk/src/lib.rs +759 -442
- package/sdk-core/crates/sdk/src/workflow_context/options.rs +64 -35
- package/sdk-core/crates/sdk/src/workflow_context.rs +1033 -289
- package/sdk-core/crates/sdk/src/workflow_future.rs +277 -213
- package/sdk-core/crates/sdk/src/workflows.rs +711 -0
- package/sdk-core/crates/sdk-core/Cargo.toml +59 -65
- package/sdk-core/crates/sdk-core/benches/workflow_replay_bench.rs +45 -54
- package/sdk-core/crates/sdk-core/machine_coverage/ActivityMachine_Coverage.puml +1 -1
- package/sdk-core/crates/sdk-core/src/abstractions.rs +6 -10
- package/sdk-core/crates/sdk-core/src/core_tests/activity_tasks.rs +6 -5
- package/sdk-core/crates/sdk-core/src/core_tests/mod.rs +22 -21
- package/sdk-core/crates/sdk-core/src/core_tests/queries.rs +21 -25
- package/sdk-core/crates/sdk-core/src/core_tests/replay_flag.rs +7 -10
- package/sdk-core/crates/sdk-core/src/core_tests/updates.rs +14 -17
- package/sdk-core/crates/sdk-core/src/core_tests/workers.rs +647 -27
- package/sdk-core/crates/sdk-core/src/core_tests/workflow_tasks.rs +46 -41
- package/sdk-core/crates/sdk-core/src/ephemeral_server/mod.rs +13 -16
- package/sdk-core/crates/sdk-core/src/histfetch.rs +20 -10
- package/sdk-core/crates/sdk-core/src/lib.rs +60 -123
- package/sdk-core/crates/sdk-core/src/pollers/mod.rs +4 -9
- package/sdk-core/crates/sdk-core/src/pollers/poll_buffer.rs +411 -32
- package/sdk-core/crates/sdk-core/src/protosext/mod.rs +2 -2
- package/sdk-core/crates/sdk-core/src/replay/mod.rs +14 -5
- package/sdk-core/crates/sdk-core/src/telemetry/metrics.rs +183 -198
- package/sdk-core/crates/sdk-core/src/telemetry/mod.rs +3 -281
- package/sdk-core/crates/sdk-core/src/test_help/integ_helpers.rs +35 -16
- package/sdk-core/crates/sdk-core/src/test_help/unit_helpers.rs +3 -6
- package/sdk-core/crates/sdk-core/src/worker/activities/activity_heartbeat_manager.rs +1 -0
- package/sdk-core/crates/sdk-core/src/worker/activities/local_activities.rs +11 -14
- package/sdk-core/crates/sdk-core/src/worker/activities.rs +16 -19
- package/sdk-core/crates/sdk-core/src/worker/client/mocks.rs +11 -5
- package/sdk-core/crates/sdk-core/src/worker/client.rs +104 -86
- package/sdk-core/crates/sdk-core/src/worker/heartbeat.rs +10 -14
- package/sdk-core/crates/sdk-core/src/worker/mod.rs +1175 -241
- package/sdk-core/crates/sdk-core/src/worker/nexus.rs +150 -23
- package/sdk-core/crates/sdk-core/src/worker/slot_provider.rs +2 -2
- package/sdk-core/crates/sdk-core/src/worker/tuner/fixed_size.rs +2 -2
- package/sdk-core/crates/sdk-core/src/worker/tuner/resource_based.rs +25 -27
- package/sdk-core/crates/sdk-core/src/worker/tuner.rs +64 -44
- package/sdk-core/crates/sdk-core/src/worker/workflow/driven_workflow.rs +9 -3
- package/sdk-core/crates/sdk-core/src/worker/workflow/machines/patch_state_machine.rs +5 -8
- package/sdk-core/crates/sdk-core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +21 -22
- package/sdk-core/crates/sdk-core/src/worker/workflow/machines/workflow_machines.rs +28 -4
- package/sdk-core/crates/sdk-core/src/worker/workflow/managed_run.rs +20 -41
- package/sdk-core/crates/sdk-core/src/worker/workflow/mod.rs +50 -9
- package/sdk-core/crates/sdk-core/src/worker/workflow/run_cache.rs +4 -7
- package/sdk-core/crates/sdk-core/src/worker/workflow/wft_extraction.rs +2 -4
- package/sdk-core/crates/sdk-core/src/worker/workflow/wft_poller.rs +8 -9
- package/sdk-core/crates/sdk-core/src/worker/workflow/workflow_stream.rs +1 -3
- package/sdk-core/crates/sdk-core/tests/activities_procmacro.rs +6 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/basic_pass.rs +54 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.rs +18 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.rs +14 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/multi_arg_pass.rs +48 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_input_pass.rs +14 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_return_type_pass.rs +19 -0
- package/sdk-core/crates/sdk-core/tests/cloud_tests.rs +14 -5
- package/sdk-core/crates/sdk-core/tests/common/activity_functions.rs +55 -0
- package/sdk-core/crates/sdk-core/tests/common/mod.rs +281 -236
- package/sdk-core/crates/sdk-core/tests/common/workflows.rs +41 -28
- package/sdk-core/crates/sdk-core/tests/global_metric_tests.rs +9 -14
- package/sdk-core/crates/sdk-core/tests/heavy_tests/fuzzy_workflow.rs +73 -66
- package/sdk-core/crates/sdk-core/tests/heavy_tests.rs +306 -268
- package/sdk-core/crates/sdk-core/tests/integ_tests/async_activity_client_tests.rs +230 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/client_tests.rs +94 -57
- package/sdk-core/crates/sdk-core/tests/integ_tests/data_converter_tests.rs +381 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +37 -38
- package/sdk-core/crates/sdk-core/tests/integ_tests/heartbeat_tests.rs +49 -40
- package/sdk-core/crates/sdk-core/tests/integ_tests/metrics_tests.rs +447 -300
- package/sdk-core/crates/sdk-core/tests/integ_tests/pagination_tests.rs +50 -45
- package/sdk-core/crates/sdk-core/tests/integ_tests/polling_tests.rs +157 -157
- package/sdk-core/crates/sdk-core/tests/integ_tests/queries_tests.rs +103 -89
- package/sdk-core/crates/sdk-core/tests/integ_tests/update_tests.rs +609 -463
- package/sdk-core/crates/sdk-core/tests/integ_tests/visibility_tests.rs +80 -62
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_heartbeat_tests.rs +389 -265
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_tests.rs +250 -185
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_versioning_tests.rs +52 -49
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_client_tests.rs +180 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/activities.rs +437 -327
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +82 -58
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +56 -30
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +364 -251
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/client_interactions.rs +552 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +110 -46
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +243 -149
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/eager.rs +98 -32
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +1475 -1040
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +73 -43
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +402 -245
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/patches.rs +343 -207
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/queries.rs +415 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/replay.rs +96 -36
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/resets.rs +155 -140
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/signals.rs +183 -113
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +85 -44
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/timers.rs +142 -48
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +73 -56
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests.rs +365 -242
- package/sdk-core/crates/sdk-core/tests/main.rs +22 -16
- package/sdk-core/crates/sdk-core/tests/manual_tests.rs +233 -187
- package/sdk-core/crates/sdk-core/tests/runner.rs +4 -6
- package/sdk-core/crates/sdk-core/tests/shared_tests/mod.rs +73 -27
- package/sdk-core/crates/sdk-core/tests/shared_tests/priority.rs +107 -84
- package/sdk-core/crates/sdk-core/tests/workflows_procmacro.rs +6 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.rs +26 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/basic_pass.rs +49 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/minimal_pass.rs +21 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.rs +26 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.rs +21 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core-c-bridge/Cargo.toml +8 -1
- package/sdk-core/crates/sdk-core-c-bridge/include/temporal-sdk-core-c-bridge.h +37 -26
- package/sdk-core/crates/sdk-core-c-bridge/src/client.rs +180 -87
- package/sdk-core/crates/sdk-core-c-bridge/src/lib.rs +89 -5
- package/sdk-core/crates/sdk-core-c-bridge/src/metric.rs +10 -16
- package/sdk-core/crates/sdk-core-c-bridge/src/runtime.rs +59 -67
- package/sdk-core/crates/sdk-core-c-bridge/src/testing.rs +10 -10
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/context.rs +57 -22
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/mod.rs +108 -12
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/utils.rs +9 -52
- package/sdk-core/crates/sdk-core-c-bridge/src/worker.rs +74 -91
- package/sdk-core/rustfmt.toml +2 -1
- package/src/client.rs +206 -289
- package/src/helpers/try_into_js.rs +88 -2
- package/src/metrics.rs +277 -35
- package/src/runtime.rs +94 -45
- package/src/testing.rs +9 -16
- package/src/worker.rs +86 -68
- package/ts/native.ts +39 -3
- package/sdk-core/crates/client/src/workflow_handle/mod.rs +0 -212
- package/sdk-core/crates/common/src/errors.rs +0 -85
- package/sdk-core/crates/common/tests/worker_task_types_test.rs +0 -129
- package/sdk-core/crates/macros/LICENSE.txt +0 -21
- package/sdk-core/crates/sdk/src/activity_context.rs +0 -238
- package/sdk-core/crates/sdk/src/app_data.rs +0 -37
- package/sdk-core/crates/sdk-core/tests/integ_tests/activity_functions.rs +0 -5
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +0 -61
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
use crate::common::{
|
|
2
|
-
CoreWfStarter, WorkflowHandleExt,
|
|
2
|
+
CoreWfStarter, WorkflowHandleExt, activity_functions::StdActivities, init_core_and_create_wf,
|
|
3
|
+
init_core_replay_preloaded,
|
|
3
4
|
};
|
|
4
5
|
use anyhow::anyhow;
|
|
5
6
|
use assert_matches::assert_matches;
|
|
6
|
-
use futures_util::{
|
|
7
|
+
use futures_util::{future, future::join_all};
|
|
7
8
|
use std::{
|
|
8
9
|
sync::{
|
|
9
|
-
|
|
10
|
+
LazyLock,
|
|
10
11
|
atomic::{AtomicBool, AtomicUsize, Ordering},
|
|
11
12
|
},
|
|
12
13
|
time::Duration,
|
|
13
14
|
};
|
|
14
15
|
use temporalio_client::{
|
|
15
|
-
Client, NamespacedClient,
|
|
16
|
+
Client, NamespacedClient, UntypedSignal, UntypedUpdate, UntypedWorkflow,
|
|
17
|
+
WorkflowExecuteUpdateOptions, WorkflowExecutionInfo, WorkflowSignalOptions,
|
|
18
|
+
WorkflowStartOptions, grpc::WorkflowService,
|
|
16
19
|
};
|
|
17
20
|
use temporalio_common::{
|
|
18
|
-
|
|
21
|
+
data_converters::RawValue,
|
|
22
|
+
prost_dur,
|
|
19
23
|
protos::{
|
|
20
24
|
coresdk::{
|
|
21
|
-
ActivityTaskCompletion,
|
|
25
|
+
ActivityTaskCompletion,
|
|
22
26
|
activity_result::ActivityExecutionResult,
|
|
23
27
|
workflow_activation::{
|
|
24
28
|
WorkflowActivationJob, remove_from_cache::EvictionReason, workflow_activation_job,
|
|
@@ -30,16 +34,21 @@ use temporalio_common::{
|
|
|
30
34
|
},
|
|
31
35
|
temporal::api::{
|
|
32
36
|
common::v1::WorkflowExecution,
|
|
33
|
-
enums::v1::{EventType, ResetReapplyType
|
|
34
|
-
|
|
35
|
-
workflowservice::v1::ResetWorkflowExecutionRequest,
|
|
37
|
+
enums::v1::{EventType, ResetReapplyType},
|
|
38
|
+
workflowservice::v1::{ResetStickyTaskQueueRequest, ResetWorkflowExecutionRequest},
|
|
36
39
|
},
|
|
37
40
|
test_utils::start_timer_cmd,
|
|
38
41
|
},
|
|
39
42
|
worker::WorkerTaskTypes,
|
|
40
43
|
};
|
|
41
|
-
use
|
|
44
|
+
use temporalio_macros::{activities, workflow, workflow_methods};
|
|
45
|
+
use temporalio_sdk::{
|
|
46
|
+
ActivityOptions, LocalActivityOptions, SyncWorkflowContext, WorkflowContext,
|
|
47
|
+
WorkflowContextView, WorkflowResult,
|
|
48
|
+
activities::{ActivityContext, ActivityError},
|
|
49
|
+
};
|
|
42
50
|
use temporalio_sdk_core::{
|
|
51
|
+
Worker,
|
|
43
52
|
replay::HistoryForReplay,
|
|
44
53
|
test_help::{WorkerTestHelpers, drain_pollers_and_shutdown},
|
|
45
54
|
};
|
|
@@ -73,18 +82,18 @@ async fn update_workflow(#[values(FailUpdate::Yes, FailUpdate::No)] will_fail: F
|
|
|
73
82
|
will_fail,
|
|
74
83
|
CompleteWorkflow::Yes,
|
|
75
84
|
core.as_ref(),
|
|
76
|
-
client
|
|
85
|
+
&client,
|
|
77
86
|
)
|
|
78
87
|
.await;
|
|
79
88
|
|
|
80
89
|
// Make sure replay works
|
|
81
|
-
let
|
|
82
|
-
.
|
|
90
|
+
let events = client
|
|
91
|
+
.get_workflow_handle::<UntypedWorkflow>(workflow_id)
|
|
92
|
+
.fetch_history(Default::default())
|
|
83
93
|
.await
|
|
84
94
|
.unwrap()
|
|
85
|
-
.
|
|
86
|
-
|
|
87
|
-
let with_id = HistoryForReplay::new(history, workflow_id.to_string());
|
|
95
|
+
.into_events();
|
|
96
|
+
let with_id = HistoryForReplay::new(events, workflow_id.to_string());
|
|
88
97
|
let replay_worker = init_core_replay_preloaded(workflow_id, [with_id]);
|
|
89
98
|
// Init workflow comes by itself
|
|
90
99
|
let act = replay_worker.poll_workflow_activation().await.unwrap();
|
|
@@ -92,7 +101,7 @@ async fn update_workflow(#[values(FailUpdate::Yes, FailUpdate::No)] will_fail: F
|
|
|
92
101
|
.complete_workflow_activation(WorkflowActivationCompletion::empty(act.run_id))
|
|
93
102
|
.await
|
|
94
103
|
.unwrap();
|
|
95
|
-
handle_update(will_fail, CompleteWorkflow::Yes, replay_worker
|
|
104
|
+
handle_update(will_fail, CompleteWorkflow::Yes, &replay_worker, 0).await;
|
|
96
105
|
}
|
|
97
106
|
|
|
98
107
|
#[tokio::test]
|
|
@@ -107,7 +116,7 @@ async fn reapplied_updates_due_to_reset() {
|
|
|
107
116
|
FailUpdate::No,
|
|
108
117
|
CompleteWorkflow::Yes,
|
|
109
118
|
core.as_ref(),
|
|
110
|
-
client
|
|
119
|
+
&client,
|
|
111
120
|
)
|
|
112
121
|
.await;
|
|
113
122
|
|
|
@@ -116,12 +125,12 @@ async fn reapplied_updates_due_to_reset() {
|
|
|
116
125
|
|
|
117
126
|
let mut client_mut = client.clone();
|
|
118
127
|
let reset_response = WorkflowService::reset_workflow_execution(
|
|
119
|
-
|
|
128
|
+
&mut client_mut,
|
|
120
129
|
#[allow(deprecated)]
|
|
121
130
|
ResetWorkflowExecutionRequest {
|
|
122
131
|
namespace: client.namespace(),
|
|
123
132
|
workflow_execution: Some(WorkflowExecution {
|
|
124
|
-
workflow_id: workflow_id.
|
|
133
|
+
workflow_id: workflow_id.to_string(),
|
|
125
134
|
run_id: pre_reset_run_id.clone(),
|
|
126
135
|
}),
|
|
127
136
|
workflow_task_finish_event_id,
|
|
@@ -147,32 +156,31 @@ async fn reapplied_updates_due_to_reset() {
|
|
|
147
156
|
FailUpdate::No,
|
|
148
157
|
CompleteWorkflow::Yes,
|
|
149
158
|
core.as_ref(),
|
|
150
|
-
client
|
|
159
|
+
&client,
|
|
151
160
|
)
|
|
152
161
|
.await;
|
|
153
162
|
|
|
154
163
|
assert_eq!(post_reset_run_id, reset_response.run_id);
|
|
155
164
|
|
|
156
165
|
// Make sure replay works
|
|
157
|
-
let
|
|
158
|
-
.
|
|
159
|
-
.
|
|
160
|
-
.
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
166
|
+
let events = WorkflowExecutionInfo {
|
|
167
|
+
namespace: client.namespace(),
|
|
168
|
+
workflow_id: workflow_id.to_string(),
|
|
169
|
+
run_id: Some(post_reset_run_id.clone()),
|
|
170
|
+
first_execution_run_id: None,
|
|
171
|
+
}
|
|
172
|
+
.bind_untyped(client.clone())
|
|
173
|
+
.fetch_history(Default::default())
|
|
174
|
+
.await
|
|
175
|
+
.unwrap()
|
|
176
|
+
.into_events();
|
|
177
|
+
let with_id = HistoryForReplay::new(events, workflow_id.to_string());
|
|
164
178
|
|
|
165
179
|
let replay_worker = init_core_replay_preloaded(workflow_id, [with_id]);
|
|
166
180
|
// We now recapitulate the actions that the worker took on first execution above, pretending
|
|
167
181
|
// that we always followed the post-reset history.
|
|
168
182
|
// First, we handled the post-reset reapplied update and did not complete the workflow.
|
|
169
|
-
handle_update(
|
|
170
|
-
FailUpdate::No,
|
|
171
|
-
CompleteWorkflow::No,
|
|
172
|
-
replay_worker.as_ref(),
|
|
173
|
-
2,
|
|
174
|
-
)
|
|
175
|
-
.await;
|
|
183
|
+
handle_update(FailUpdate::No, CompleteWorkflow::No, &replay_worker, 2).await;
|
|
176
184
|
// Then the timer fires
|
|
177
185
|
let act = replay_worker.poll_workflow_activation().await.unwrap();
|
|
178
186
|
replay_worker
|
|
@@ -180,13 +188,7 @@ async fn reapplied_updates_due_to_reset() {
|
|
|
180
188
|
.await
|
|
181
189
|
.unwrap();
|
|
182
190
|
// Then the client sent a second update; we handled it and completed the workflow.
|
|
183
|
-
handle_update(
|
|
184
|
-
FailUpdate::No,
|
|
185
|
-
CompleteWorkflow::Yes,
|
|
186
|
-
replay_worker.as_ref(),
|
|
187
|
-
0,
|
|
188
|
-
)
|
|
189
|
-
.await;
|
|
191
|
+
handle_update(FailUpdate::No, CompleteWorkflow::Yes, &replay_worker, 0).await;
|
|
190
192
|
|
|
191
193
|
drain_pollers_and_shutdown(&replay_worker).await;
|
|
192
194
|
}
|
|
@@ -197,8 +199,8 @@ async fn send_and_handle_update(
|
|
|
197
199
|
update_id: &str,
|
|
198
200
|
fail_update: FailUpdate,
|
|
199
201
|
complete_workflow: CompleteWorkflow,
|
|
200
|
-
core: &
|
|
201
|
-
client: &
|
|
202
|
+
core: &Worker,
|
|
203
|
+
client: &Client,
|
|
202
204
|
) -> String {
|
|
203
205
|
// Complete first task with no commands
|
|
204
206
|
let act = core.poll_workflow_activation().await.unwrap();
|
|
@@ -206,30 +208,32 @@ async fn send_and_handle_update(
|
|
|
206
208
|
.await
|
|
207
209
|
.unwrap();
|
|
208
210
|
|
|
211
|
+
let handle = WorkflowExecutionInfo {
|
|
212
|
+
namespace: client.namespace(),
|
|
213
|
+
workflow_id: workflow_id.to_string(),
|
|
214
|
+
run_id: Some(act.run_id.clone()),
|
|
215
|
+
first_execution_run_id: None,
|
|
216
|
+
}
|
|
217
|
+
.bind_untyped(client.clone());
|
|
218
|
+
|
|
209
219
|
// Send the update to the server
|
|
210
220
|
let update_task = async {
|
|
211
|
-
|
|
212
|
-
.
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
WaitPolicy {
|
|
217
|
-
lifecycle_stage: UpdateWorkflowExecutionLifecycleStage::Completed as i32,
|
|
218
|
-
},
|
|
219
|
-
Some("hi".into()),
|
|
221
|
+
handle
|
|
222
|
+
.execute_update(
|
|
223
|
+
UntypedUpdate::new(update_id),
|
|
224
|
+
RawValue::from_value(&"hi", client.data_converter().payload_converter()),
|
|
225
|
+
WorkflowExecuteUpdateOptions::default(),
|
|
220
226
|
)
|
|
221
227
|
.await
|
|
222
|
-
.unwrap()
|
|
223
228
|
};
|
|
224
229
|
|
|
225
230
|
// Accept update, complete update and complete workflow
|
|
226
231
|
let processing_task = handle_update(fail_update, complete_workflow, core, 0);
|
|
227
232
|
let (ur, _) = join!(update_task, processing_task);
|
|
228
233
|
|
|
229
|
-
let v = ur.outcome.unwrap().value.unwrap();
|
|
230
234
|
match fail_update {
|
|
231
|
-
FailUpdate::Yes =>
|
|
232
|
-
FailUpdate::No =>
|
|
235
|
+
FailUpdate::Yes => assert!(ur.is_err()),
|
|
236
|
+
FailUpdate::No => assert!(ur.is_ok()),
|
|
233
237
|
}
|
|
234
238
|
act.run_id
|
|
235
239
|
}
|
|
@@ -241,7 +245,7 @@ async fn send_and_handle_update(
|
|
|
241
245
|
async fn handle_update(
|
|
242
246
|
fail_update: FailUpdate,
|
|
243
247
|
complete_workflow: CompleteWorkflow,
|
|
244
|
-
core: &
|
|
248
|
+
core: &Worker,
|
|
245
249
|
update_job_index: usize,
|
|
246
250
|
) {
|
|
247
251
|
let act = core.poll_workflow_activation().await.unwrap();
|
|
@@ -313,20 +317,24 @@ async fn update_rejection() {
|
|
|
313
317
|
.await
|
|
314
318
|
.unwrap();
|
|
315
319
|
|
|
320
|
+
let handle = WorkflowExecutionInfo {
|
|
321
|
+
namespace: client.namespace(),
|
|
322
|
+
workflow_id: workflow_id.clone(),
|
|
323
|
+
run_id: Some(res.run_id.clone()),
|
|
324
|
+
first_execution_run_id: None,
|
|
325
|
+
}
|
|
326
|
+
.bind_untyped(client.clone());
|
|
327
|
+
|
|
316
328
|
// Send the update to the server
|
|
317
329
|
let update_task = async {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
lifecycle_stage: UpdateWorkflowExecutionLifecycleStage::Completed as i32,
|
|
325
|
-
},
|
|
326
|
-
Some("hi".into()),
|
|
330
|
+
// rejected
|
|
331
|
+
let _ = handle
|
|
332
|
+
.execute_update(
|
|
333
|
+
UntypedUpdate::new(update_id),
|
|
334
|
+
RawValue::from_value(&"hi", client.data_converter().payload_converter()),
|
|
335
|
+
WorkflowExecuteUpdateOptions::default(),
|
|
327
336
|
)
|
|
328
|
-
.await
|
|
329
|
-
.unwrap();
|
|
337
|
+
.await;
|
|
330
338
|
};
|
|
331
339
|
|
|
332
340
|
let processing_task = async {
|
|
@@ -355,13 +363,13 @@ async fn update_rejection() {
|
|
|
355
363
|
core.complete_execution(&res.run_id).await;
|
|
356
364
|
};
|
|
357
365
|
join!(update_task, processing_task);
|
|
358
|
-
let
|
|
359
|
-
.
|
|
366
|
+
let events = client
|
|
367
|
+
.get_workflow_handle::<UntypedWorkflow>(&workflow_id)
|
|
368
|
+
.fetch_history(Default::default())
|
|
360
369
|
.await
|
|
361
370
|
.unwrap()
|
|
362
|
-
.
|
|
363
|
-
|
|
364
|
-
let has_update_event = history.events.iter().any(|e| {
|
|
371
|
+
.into_events();
|
|
372
|
+
let has_update_event = events.iter().any(|e| {
|
|
365
373
|
matches!(
|
|
366
374
|
e.event_type(),
|
|
367
375
|
EventType::WorkflowExecutionUpdateAccepted | EventType::WorkflowExecutionUpdateRejected
|
|
@@ -388,17 +396,21 @@ async fn update_insta_complete(#[values(true, false)] accept_first: bool) {
|
|
|
388
396
|
.await
|
|
389
397
|
.unwrap();
|
|
390
398
|
|
|
399
|
+
let handle = WorkflowExecutionInfo {
|
|
400
|
+
namespace: client.namespace(),
|
|
401
|
+
workflow_id,
|
|
402
|
+
run_id: Some(res.run_id.clone()),
|
|
403
|
+
first_execution_run_id: None,
|
|
404
|
+
}
|
|
405
|
+
.bind_untyped(client.clone());
|
|
406
|
+
|
|
391
407
|
// Send the update to the server
|
|
392
408
|
let (update_task, stop_wait_update) = future::abortable(async {
|
|
393
|
-
|
|
394
|
-
.
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
WaitPolicy {
|
|
399
|
-
lifecycle_stage: UpdateWorkflowExecutionLifecycleStage::Completed as i32,
|
|
400
|
-
},
|
|
401
|
-
Some("hi".into()),
|
|
409
|
+
handle
|
|
410
|
+
.execute_update(
|
|
411
|
+
UntypedUpdate::new(update_id),
|
|
412
|
+
RawValue::from_value(&"hi", client.data_converter().payload_converter()),
|
|
413
|
+
WorkflowExecuteUpdateOptions::default(),
|
|
402
414
|
)
|
|
403
415
|
.await
|
|
404
416
|
.unwrap();
|
|
@@ -477,17 +489,21 @@ async fn update_complete_after_accept_without_new_task() {
|
|
|
477
489
|
.await
|
|
478
490
|
.unwrap();
|
|
479
491
|
|
|
492
|
+
let handle = WorkflowExecutionInfo {
|
|
493
|
+
namespace: client.namespace(),
|
|
494
|
+
workflow_id,
|
|
495
|
+
run_id: Some(res.run_id.clone()),
|
|
496
|
+
first_execution_run_id: None,
|
|
497
|
+
}
|
|
498
|
+
.bind_untyped(client.clone());
|
|
499
|
+
|
|
480
500
|
// Send the update to the server
|
|
481
501
|
let update_task = async {
|
|
482
|
-
|
|
483
|
-
.
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
WaitPolicy {
|
|
488
|
-
lifecycle_stage: UpdateWorkflowExecutionLifecycleStage::Completed as i32,
|
|
489
|
-
},
|
|
490
|
-
Some("hi".into()),
|
|
502
|
+
handle
|
|
503
|
+
.execute_update(
|
|
504
|
+
UntypedUpdate::new(update_id),
|
|
505
|
+
RawValue::from_value(&"hi", client.data_converter().payload_converter()),
|
|
506
|
+
WorkflowExecuteUpdateOptions::default(),
|
|
491
507
|
)
|
|
492
508
|
.await
|
|
493
509
|
.unwrap();
|
|
@@ -565,30 +581,26 @@ async fn update_speculative_wft() {
|
|
|
565
581
|
|
|
566
582
|
let update_id = "some_update";
|
|
567
583
|
|
|
584
|
+
let handle = client.get_workflow_handle::<UntypedWorkflow>(workflow_id);
|
|
585
|
+
|
|
568
586
|
// Send update after the timer has fired
|
|
569
587
|
let barr = Barrier::new(2);
|
|
570
588
|
let sender_task = async {
|
|
571
589
|
barr.wait().await;
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
lifecycle_stage: UpdateWorkflowExecutionLifecycleStage::Completed as i32,
|
|
579
|
-
},
|
|
580
|
-
Some("hi".into()),
|
|
590
|
+
// rejected
|
|
591
|
+
let _ = handle
|
|
592
|
+
.execute_update(
|
|
593
|
+
UntypedUpdate::new(update_id),
|
|
594
|
+
RawValue::from_value(&"hi", client.data_converter().payload_converter()),
|
|
595
|
+
WorkflowExecuteUpdateOptions::default(),
|
|
581
596
|
)
|
|
582
|
-
.await
|
|
583
|
-
.unwrap();
|
|
597
|
+
.await;
|
|
584
598
|
barr.wait().await;
|
|
585
|
-
|
|
586
|
-
.
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
None,
|
|
591
|
-
None,
|
|
599
|
+
handle
|
|
600
|
+
.signal(
|
|
601
|
+
UntypedSignal::new("hi"),
|
|
602
|
+
RawValue::empty(),
|
|
603
|
+
WorkflowSignalOptions::default(),
|
|
592
604
|
)
|
|
593
605
|
.await
|
|
594
606
|
.unwrap();
|
|
@@ -649,63 +661,70 @@ async fn update_with_local_acts() {
|
|
|
649
661
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
650
662
|
// Short task timeout to get activities to heartbeat without taking ages
|
|
651
663
|
starter.workflow_options.task_timeout = Some(Duration::from_secs(1));
|
|
664
|
+
starter.sdk_config.register_activities(StdActivities);
|
|
652
665
|
let mut worker = starter.worker().await;
|
|
653
|
-
let client = starter.get_client().await;
|
|
654
|
-
worker.register_wf(wf_name.to_owned(), move |ctx: WfContext| async move {
|
|
655
|
-
ctx.update_handler(
|
|
656
|
-
"update",
|
|
657
|
-
|_: &_, _: ()| Ok(()),
|
|
658
|
-
move |ctx: UpdateContext, _: ()| async move {
|
|
659
|
-
ctx.wf_ctx
|
|
660
|
-
.local_activity(LocalActivityOptions {
|
|
661
|
-
activity_type: "echo_activity".to_string(),
|
|
662
|
-
input: "hi!".as_json_payload().expect("serializes fine"),
|
|
663
|
-
..Default::default()
|
|
664
|
-
})
|
|
665
|
-
.await;
|
|
666
|
-
Ok("hi")
|
|
667
|
-
},
|
|
668
|
-
);
|
|
669
|
-
let mut sig = ctx.make_signal_channel("done");
|
|
670
|
-
sig.next().await;
|
|
671
|
-
Ok(().into())
|
|
672
|
-
});
|
|
673
|
-
worker.register_activity(
|
|
674
|
-
"echo_activity",
|
|
675
|
-
|_ctx: ActContext, echo_me: String| async move {
|
|
676
|
-
// Sleep so we'll heartbeat
|
|
677
|
-
tokio::time::sleep(Duration::from_secs(3)).await;
|
|
678
|
-
Ok(echo_me)
|
|
679
|
-
},
|
|
680
|
-
);
|
|
681
666
|
|
|
682
|
-
|
|
683
|
-
|
|
667
|
+
#[workflow]
|
|
668
|
+
#[derive(Default)]
|
|
669
|
+
struct UpdateWithLocalActsWf {
|
|
670
|
+
done: bool,
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
#[workflow_methods]
|
|
674
|
+
impl UpdateWithLocalActsWf {
|
|
675
|
+
#[run]
|
|
676
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
677
|
+
ctx.wait_condition(|s| s.done).await;
|
|
678
|
+
Ok(())
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
#[signal]
|
|
682
|
+
fn done_signal(&mut self, _ctx: &mut SyncWorkflowContext<Self>, _: ()) {
|
|
683
|
+
self.done = true;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
#[update]
|
|
687
|
+
async fn do_update(
|
|
688
|
+
ctx: &mut WorkflowContext<Self>,
|
|
689
|
+
_: (),
|
|
690
|
+
) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
|
|
691
|
+
ctx.start_local_activity(
|
|
692
|
+
StdActivities::delay,
|
|
693
|
+
Duration::from_secs(3),
|
|
694
|
+
LocalActivityOptions::default(),
|
|
695
|
+
)
|
|
696
|
+
.await?;
|
|
697
|
+
Ok("hi".to_string())
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
worker.register_workflow::<UpdateWithLocalActsWf>();
|
|
702
|
+
let task_queue = starter.get_task_queue().to_owned();
|
|
703
|
+
let handle = worker
|
|
704
|
+
.submit_workflow(
|
|
705
|
+
UpdateWithLocalActsWf::run,
|
|
706
|
+
(),
|
|
707
|
+
WorkflowStartOptions::new(task_queue, starter.get_wf_id().to_owned()).build(),
|
|
708
|
+
)
|
|
709
|
+
.await
|
|
710
|
+
.unwrap();
|
|
684
711
|
let update = async {
|
|
685
|
-
// make sure update has a chance to get registered
|
|
686
|
-
tokio::time::sleep(Duration::from_millis(100)).await;
|
|
687
712
|
// do a handful at once
|
|
688
713
|
let updates = (1..=5).map(|_| {
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
WaitPolicy {
|
|
694
|
-
lifecycle_stage: UpdateWorkflowExecutionLifecycleStage::Completed as i32,
|
|
695
|
-
},
|
|
696
|
-
[().as_json_payload().unwrap()].into_payloads(),
|
|
714
|
+
handle.execute_update(
|
|
715
|
+
UpdateWithLocalActsWf::do_update,
|
|
716
|
+
(),
|
|
717
|
+
WorkflowExecuteUpdateOptions::default(),
|
|
697
718
|
)
|
|
698
719
|
});
|
|
699
720
|
for res in join_all(updates).await {
|
|
700
|
-
assert!(res.unwrap()
|
|
721
|
+
assert!(res.unwrap() == "hi");
|
|
701
722
|
}
|
|
702
|
-
|
|
703
|
-
.
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
None,
|
|
708
|
-
None,
|
|
723
|
+
handle
|
|
724
|
+
.signal(
|
|
725
|
+
UpdateWithLocalActsWf::done_signal,
|
|
726
|
+
(),
|
|
727
|
+
WorkflowSignalOptions::default(),
|
|
709
728
|
)
|
|
710
729
|
.await
|
|
711
730
|
.unwrap();
|
|
@@ -724,37 +743,57 @@ async fn update_with_local_acts() {
|
|
|
724
743
|
async fn update_rejection_sdk() {
|
|
725
744
|
let wf_name = "update_rejection_sdk";
|
|
726
745
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
727
|
-
starter
|
|
728
|
-
.worker_config
|
|
729
|
-
.task_types(WorkerTaskTypes::workflow_only());
|
|
746
|
+
starter.sdk_config.task_types = WorkerTaskTypes::workflow_only();
|
|
730
747
|
let mut worker = starter.worker().await;
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
ctx
|
|
739
|
-
|
|
740
|
-
|
|
748
|
+
#[workflow]
|
|
749
|
+
#[derive(Default)]
|
|
750
|
+
struct UpdateRejectionSdkWf;
|
|
751
|
+
|
|
752
|
+
#[workflow_methods]
|
|
753
|
+
impl UpdateRejectionSdkWf {
|
|
754
|
+
#[run]
|
|
755
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
756
|
+
ctx.timer(Duration::from_secs(1)).await;
|
|
757
|
+
Ok(())
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
#[update_validator(do_update)]
|
|
761
|
+
fn validate_do_update(
|
|
762
|
+
&self,
|
|
763
|
+
_ctx: &WorkflowContextView,
|
|
764
|
+
_: &(),
|
|
765
|
+
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|
766
|
+
Err("ahhhhh noooo".into())
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
#[update]
|
|
770
|
+
async fn do_update(
|
|
771
|
+
_ctx: &mut WorkflowContext<Self>,
|
|
772
|
+
_: (),
|
|
773
|
+
) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
|
|
774
|
+
Ok("hi".to_string())
|
|
775
|
+
}
|
|
776
|
+
}
|
|
741
777
|
|
|
742
|
-
|
|
743
|
-
let
|
|
778
|
+
worker.register_workflow::<UpdateRejectionSdkWf>();
|
|
779
|
+
let task_queue = starter.get_task_queue().to_owned();
|
|
780
|
+
let handle = worker
|
|
781
|
+
.submit_workflow(
|
|
782
|
+
UpdateRejectionSdkWf::run,
|
|
783
|
+
(),
|
|
784
|
+
WorkflowStartOptions::new(task_queue, starter.get_wf_id().to_owned()).build(),
|
|
785
|
+
)
|
|
786
|
+
.await
|
|
787
|
+
.unwrap();
|
|
744
788
|
let update = async {
|
|
745
|
-
let res =
|
|
746
|
-
.
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
WaitPolicy {
|
|
751
|
-
lifecycle_stage: UpdateWorkflowExecutionLifecycleStage::Completed as i32,
|
|
752
|
-
},
|
|
753
|
-
[().as_json_payload().unwrap()].into_payloads(),
|
|
789
|
+
let res = handle
|
|
790
|
+
.execute_update(
|
|
791
|
+
UpdateRejectionSdkWf::do_update,
|
|
792
|
+
(),
|
|
793
|
+
WorkflowExecuteUpdateOptions::default(),
|
|
754
794
|
)
|
|
755
|
-
.await
|
|
756
|
-
|
|
757
|
-
assert!(!res.outcome.unwrap().is_success());
|
|
795
|
+
.await;
|
|
796
|
+
assert!(res.is_err());
|
|
758
797
|
};
|
|
759
798
|
let run = async {
|
|
760
799
|
worker.run_until_done().await.unwrap();
|
|
@@ -770,37 +809,48 @@ async fn update_rejection_sdk() {
|
|
|
770
809
|
async fn update_fail_sdk() {
|
|
771
810
|
let wf_name = "update_fail_sdk";
|
|
772
811
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
773
|
-
starter
|
|
774
|
-
.worker_config
|
|
775
|
-
.task_types(WorkerTaskTypes::workflow_only());
|
|
812
|
+
starter.sdk_config.task_types = WorkerTaskTypes::workflow_only();
|
|
776
813
|
let mut worker = starter.worker().await;
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
ctx
|
|
785
|
-
|
|
786
|
-
|
|
814
|
+
#[workflow]
|
|
815
|
+
#[derive(Default)]
|
|
816
|
+
struct UpdateFailSdkWf;
|
|
817
|
+
|
|
818
|
+
#[workflow_methods]
|
|
819
|
+
impl UpdateFailSdkWf {
|
|
820
|
+
#[run]
|
|
821
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
822
|
+
ctx.timer(Duration::from_secs(1)).await;
|
|
823
|
+
Ok(())
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
#[update]
|
|
827
|
+
async fn do_update(
|
|
828
|
+
_ctx: &mut WorkflowContext<Self>,
|
|
829
|
+
_: (),
|
|
830
|
+
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|
831
|
+
Err("nooooo".into())
|
|
832
|
+
}
|
|
833
|
+
}
|
|
787
834
|
|
|
788
|
-
|
|
789
|
-
let
|
|
835
|
+
worker.register_workflow::<UpdateFailSdkWf>();
|
|
836
|
+
let task_queue = starter.get_task_queue().to_owned();
|
|
837
|
+
let handle = worker
|
|
838
|
+
.submit_workflow(
|
|
839
|
+
UpdateFailSdkWf::run,
|
|
840
|
+
(),
|
|
841
|
+
WorkflowStartOptions::new(task_queue, starter.get_wf_id().to_owned()).build(),
|
|
842
|
+
)
|
|
843
|
+
.await
|
|
844
|
+
.unwrap();
|
|
790
845
|
let update = async {
|
|
791
|
-
let res =
|
|
792
|
-
.
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
WaitPolicy {
|
|
797
|
-
lifecycle_stage: UpdateWorkflowExecutionLifecycleStage::Completed as i32,
|
|
798
|
-
},
|
|
799
|
-
[().as_json_payload().unwrap()].into_payloads(),
|
|
846
|
+
let res = handle
|
|
847
|
+
.execute_update(
|
|
848
|
+
UpdateFailSdkWf::do_update,
|
|
849
|
+
(),
|
|
850
|
+
WorkflowExecuteUpdateOptions::default(),
|
|
800
851
|
)
|
|
801
|
-
.await
|
|
802
|
-
|
|
803
|
-
assert!(!res.outcome.unwrap().is_success());
|
|
852
|
+
.await;
|
|
853
|
+
assert!(res.is_err());
|
|
804
854
|
};
|
|
805
855
|
let run = async {
|
|
806
856
|
worker.run_until_done().await.unwrap();
|
|
@@ -816,41 +866,53 @@ async fn update_fail_sdk() {
|
|
|
816
866
|
async fn update_timer_sequence() {
|
|
817
867
|
let wf_name = "update_timer_sequence";
|
|
818
868
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
819
|
-
starter
|
|
820
|
-
.worker_config
|
|
821
|
-
.task_types(WorkerTaskTypes::workflow_only());
|
|
869
|
+
starter.sdk_config.task_types = WorkerTaskTypes::workflow_only();
|
|
822
870
|
let mut worker = starter.worker().await;
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
});
|
|
871
|
+
#[workflow]
|
|
872
|
+
#[derive(Default)]
|
|
873
|
+
struct UpdateTimerSequenceWf {
|
|
874
|
+
done: bool,
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
#[workflow_methods]
|
|
878
|
+
impl UpdateTimerSequenceWf {
|
|
879
|
+
#[run]
|
|
880
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
881
|
+
ctx.wait_condition(|s| s.done).await;
|
|
882
|
+
Ok(())
|
|
883
|
+
}
|
|
837
884
|
|
|
838
|
-
|
|
839
|
-
|
|
885
|
+
#[update]
|
|
886
|
+
async fn do_update(
|
|
887
|
+
ctx: &mut WorkflowContext<Self>,
|
|
888
|
+
_: (),
|
|
889
|
+
) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
|
|
890
|
+
ctx.timer(Duration::from_millis(1)).await;
|
|
891
|
+
ctx.timer(Duration::from_millis(1)).await;
|
|
892
|
+
ctx.state_mut(|s| s.done = true);
|
|
893
|
+
Ok("done".to_string())
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
worker.register_workflow::<UpdateTimerSequenceWf>();
|
|
898
|
+
let task_queue = starter.get_task_queue().to_owned();
|
|
899
|
+
let handle = worker
|
|
900
|
+
.submit_workflow(
|
|
901
|
+
UpdateTimerSequenceWf::run,
|
|
902
|
+
(),
|
|
903
|
+
WorkflowStartOptions::new(task_queue, starter.get_wf_id().to_owned()).build(),
|
|
904
|
+
)
|
|
905
|
+
.await
|
|
906
|
+
.unwrap();
|
|
840
907
|
let update = async {
|
|
841
|
-
let res =
|
|
842
|
-
.
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
WaitPolicy {
|
|
847
|
-
lifecycle_stage: UpdateWorkflowExecutionLifecycleStage::Completed as i32,
|
|
848
|
-
},
|
|
849
|
-
[().as_json_payload().unwrap()].into_payloads(),
|
|
908
|
+
let res = handle
|
|
909
|
+
.execute_update(
|
|
910
|
+
UpdateTimerSequenceWf::do_update,
|
|
911
|
+
(),
|
|
912
|
+
WorkflowExecuteUpdateOptions::default(),
|
|
850
913
|
)
|
|
851
|
-
.await
|
|
852
|
-
|
|
853
|
-
assert!(res.outcome.unwrap().is_success());
|
|
914
|
+
.await;
|
|
915
|
+
assert!(res.unwrap() == "done");
|
|
854
916
|
};
|
|
855
917
|
let run = async {
|
|
856
918
|
worker.run_until_done().await.unwrap();
|
|
@@ -866,44 +928,62 @@ async fn update_timer_sequence() {
|
|
|
866
928
|
async fn task_failure_during_validation() {
|
|
867
929
|
let wf_name = "task_failure_during_validation";
|
|
868
930
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
869
|
-
starter
|
|
870
|
-
.worker_config
|
|
871
|
-
.task_types(WorkerTaskTypes::workflow_only());
|
|
931
|
+
starter.sdk_config.task_types = WorkerTaskTypes::workflow_only();
|
|
872
932
|
starter.workflow_options.task_timeout = Some(Duration::from_secs(1));
|
|
873
933
|
let mut worker = starter.worker().await;
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
)
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
934
|
+
#[workflow]
|
|
935
|
+
#[derive(Default)]
|
|
936
|
+
struct TaskFailureDuringValidationWf;
|
|
937
|
+
|
|
938
|
+
#[workflow_methods]
|
|
939
|
+
impl TaskFailureDuringValidationWf {
|
|
940
|
+
#[run]
|
|
941
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
942
|
+
ctx.timer(Duration::from_secs(1)).await;
|
|
943
|
+
Ok(())
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
#[update_validator(do_update)]
|
|
947
|
+
fn validate_do_update(
|
|
948
|
+
&self,
|
|
949
|
+
_ctx: &WorkflowContextView,
|
|
950
|
+
_: &(),
|
|
951
|
+
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|
952
|
+
static FAILCT: AtomicUsize = AtomicUsize::new(0);
|
|
953
|
+
if FAILCT.fetch_add(1, Ordering::Relaxed) < 2 {
|
|
954
|
+
panic!("ahhhhhh");
|
|
955
|
+
}
|
|
956
|
+
Ok(())
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
#[update]
|
|
960
|
+
async fn do_update(
|
|
961
|
+
_ctx: &mut WorkflowContext<Self>,
|
|
962
|
+
_: (),
|
|
963
|
+
) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
|
|
964
|
+
Ok("done".to_string())
|
|
965
|
+
}
|
|
966
|
+
}
|
|
890
967
|
|
|
891
|
-
|
|
892
|
-
let
|
|
968
|
+
worker.register_workflow::<TaskFailureDuringValidationWf>();
|
|
969
|
+
let task_queue = starter.get_task_queue().to_owned();
|
|
970
|
+
let handle = worker
|
|
971
|
+
.submit_workflow(
|
|
972
|
+
TaskFailureDuringValidationWf::run,
|
|
973
|
+
(),
|
|
974
|
+
WorkflowStartOptions::new(task_queue, starter.get_wf_id().to_owned()).build(),
|
|
975
|
+
)
|
|
976
|
+
.await
|
|
977
|
+
.unwrap();
|
|
893
978
|
let update = async {
|
|
894
|
-
let res =
|
|
895
|
-
.
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
WaitPolicy {
|
|
900
|
-
lifecycle_stage: UpdateWorkflowExecutionLifecycleStage::Completed as i32,
|
|
901
|
-
},
|
|
902
|
-
[().as_json_payload().unwrap()].into_payloads(),
|
|
979
|
+
let res = handle
|
|
980
|
+
.execute_update(
|
|
981
|
+
TaskFailureDuringValidationWf::do_update,
|
|
982
|
+
(),
|
|
983
|
+
WorkflowExecuteUpdateOptions::default(),
|
|
903
984
|
)
|
|
904
|
-
.await
|
|
905
|
-
|
|
906
|
-
assert!(res.outcome.unwrap().is_success());
|
|
985
|
+
.await;
|
|
986
|
+
assert!(res.unwrap() == "done");
|
|
907
987
|
};
|
|
908
988
|
let run = async {
|
|
909
989
|
worker.run_until_done().await.unwrap();
|
|
@@ -929,42 +1009,53 @@ async fn task_failure_during_validation() {
|
|
|
929
1009
|
async fn task_failure_after_update() {
|
|
930
1010
|
let wf_name = "task_failure_after_update";
|
|
931
1011
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
932
|
-
starter
|
|
933
|
-
.worker_config
|
|
934
|
-
.task_types(WorkerTaskTypes::workflow_only());
|
|
1012
|
+
starter.sdk_config.task_types = WorkerTaskTypes::workflow_only();
|
|
935
1013
|
starter.workflow_options.task_timeout = Some(Duration::from_secs(1));
|
|
936
1014
|
let mut worker = starter.worker().await;
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
)
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
1015
|
+
#[workflow]
|
|
1016
|
+
#[derive(Default)]
|
|
1017
|
+
struct TaskFailureAfterUpdateWf;
|
|
1018
|
+
|
|
1019
|
+
#[workflow_methods]
|
|
1020
|
+
impl TaskFailureAfterUpdateWf {
|
|
1021
|
+
#[run]
|
|
1022
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
1023
|
+
static FAILCT: AtomicUsize = AtomicUsize::new(0);
|
|
1024
|
+
ctx.timer(Duration::from_millis(1)).await;
|
|
1025
|
+
if FAILCT.fetch_add(1, Ordering::Relaxed) < 1 {
|
|
1026
|
+
panic!("ahhhhhh");
|
|
1027
|
+
}
|
|
1028
|
+
Ok(())
|
|
948
1029
|
}
|
|
949
|
-
Ok(().into())
|
|
950
|
-
});
|
|
951
1030
|
|
|
952
|
-
|
|
953
|
-
|
|
1031
|
+
#[update]
|
|
1032
|
+
async fn do_update(
|
|
1033
|
+
_ctx: &mut WorkflowContext<Self>,
|
|
1034
|
+
_: (),
|
|
1035
|
+
) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
|
|
1036
|
+
Ok("done".to_string())
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
worker.register_workflow::<TaskFailureAfterUpdateWf>();
|
|
1041
|
+
let task_queue = starter.get_task_queue().to_owned();
|
|
1042
|
+
let handle = worker
|
|
1043
|
+
.submit_workflow(
|
|
1044
|
+
TaskFailureAfterUpdateWf::run,
|
|
1045
|
+
(),
|
|
1046
|
+
WorkflowStartOptions::new(task_queue, starter.get_wf_id().to_owned()).build(),
|
|
1047
|
+
)
|
|
1048
|
+
.await
|
|
1049
|
+
.unwrap();
|
|
954
1050
|
let update = async {
|
|
955
|
-
let res =
|
|
956
|
-
.
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
WaitPolicy {
|
|
961
|
-
lifecycle_stage: UpdateWorkflowExecutionLifecycleStage::Completed as i32,
|
|
962
|
-
},
|
|
963
|
-
[().as_json_payload().unwrap()].into_payloads(),
|
|
1051
|
+
let res = handle
|
|
1052
|
+
.execute_update(
|
|
1053
|
+
TaskFailureAfterUpdateWf::do_update,
|
|
1054
|
+
(),
|
|
1055
|
+
WorkflowExecuteUpdateOptions::default(),
|
|
964
1056
|
)
|
|
965
|
-
.await
|
|
966
|
-
|
|
967
|
-
assert!(res.outcome.unwrap().is_success());
|
|
1057
|
+
.await;
|
|
1058
|
+
assert!(res.unwrap() == "done");
|
|
968
1059
|
};
|
|
969
1060
|
let run = async {
|
|
970
1061
|
worker.run_until_done().await.unwrap();
|
|
@@ -976,68 +1067,94 @@ async fn task_failure_after_update() {
|
|
|
976
1067
|
.unwrap();
|
|
977
1068
|
}
|
|
978
1069
|
|
|
1070
|
+
static BARR: LazyLock<Barrier> = LazyLock::new(|| Barrier::new(2));
|
|
1071
|
+
static ACT_RAN: AtomicBool = AtomicBool::new(false);
|
|
979
1072
|
#[tokio::test]
|
|
980
1073
|
async fn worker_restarted_in_middle_of_update() {
|
|
981
1074
|
let wf_name = "worker_restarted_in_middle_of_update";
|
|
982
1075
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
1076
|
+
|
|
1077
|
+
struct BlockingActivities;
|
|
1078
|
+
#[activities]
|
|
1079
|
+
impl BlockingActivities {
|
|
1080
|
+
#[activity]
|
|
1081
|
+
async fn blocks(_ctx: ActivityContext, echo_me: String) -> Result<String, ActivityError> {
|
|
1082
|
+
BARR.wait().await;
|
|
1083
|
+
if !ACT_RAN.fetch_or(true, Ordering::Relaxed) {
|
|
1084
|
+
// On first run fail the task so we'll get retried on the new worker
|
|
1085
|
+
return Err(anyhow!("Fail first time").into());
|
|
1086
|
+
}
|
|
1087
|
+
Ok(echo_me)
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
starter.sdk_config.register_activities(BlockingActivities);
|
|
983
1092
|
let mut worker = starter.worker().await;
|
|
984
1093
|
let client = starter.get_client().await;
|
|
985
1094
|
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
..Default::default()
|
|
999
|
-
})
|
|
1000
|
-
.await;
|
|
1001
|
-
Ok(())
|
|
1002
|
-
},
|
|
1003
|
-
);
|
|
1004
|
-
let mut sig = ctx.make_signal_channel("done");
|
|
1005
|
-
sig.next().await;
|
|
1006
|
-
Ok(().into())
|
|
1007
|
-
});
|
|
1008
|
-
worker.register_activity("blocks", |_ctx: ActContext, echo_me: String| async move {
|
|
1009
|
-
BARR.wait().await;
|
|
1010
|
-
if !ACT_RAN.fetch_or(true, Ordering::Relaxed) {
|
|
1011
|
-
// On first run fail the task so we'll get retried on the new worker
|
|
1012
|
-
return Err(anyhow!("Fail first time").into());
|
|
1095
|
+
#[workflow]
|
|
1096
|
+
#[derive(Default)]
|
|
1097
|
+
struct WorkerRestartedInMiddleOfUpdateWf {
|
|
1098
|
+
done: bool,
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
#[workflow_methods]
|
|
1102
|
+
impl WorkerRestartedInMiddleOfUpdateWf {
|
|
1103
|
+
#[run]
|
|
1104
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
1105
|
+
ctx.wait_condition(|s| s.done).await;
|
|
1106
|
+
Ok(())
|
|
1013
1107
|
}
|
|
1014
|
-
Ok(echo_me)
|
|
1015
|
-
});
|
|
1016
1108
|
|
|
1017
|
-
|
|
1109
|
+
#[signal]
|
|
1110
|
+
fn done_signal(&mut self, _ctx: &mut SyncWorkflowContext<Self>, _: ()) {
|
|
1111
|
+
self.done = true;
|
|
1112
|
+
}
|
|
1018
1113
|
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1114
|
+
#[update]
|
|
1115
|
+
async fn do_update(
|
|
1116
|
+
ctx: &mut WorkflowContext<Self>,
|
|
1117
|
+
_: (),
|
|
1118
|
+
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|
1119
|
+
ctx.start_activity(
|
|
1120
|
+
BlockingActivities::blocks,
|
|
1121
|
+
"hi!".to_string(),
|
|
1122
|
+
ActivityOptions {
|
|
1123
|
+
start_to_close_timeout: Some(Duration::from_secs(2)),
|
|
1124
|
+
..Default::default()
|
|
1028
1125
|
},
|
|
1029
|
-
[().as_json_payload().unwrap()].into_payloads(),
|
|
1030
1126
|
)
|
|
1031
|
-
.await
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1127
|
+
.await?;
|
|
1128
|
+
Ok(())
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
worker.register_workflow::<WorkerRestartedInMiddleOfUpdateWf>();
|
|
1133
|
+
let task_queue = starter.get_task_queue().to_owned();
|
|
1134
|
+
let handle = worker
|
|
1135
|
+
.submit_workflow(
|
|
1136
|
+
WorkerRestartedInMiddleOfUpdateWf::run,
|
|
1137
|
+
(),
|
|
1138
|
+
WorkflowStartOptions::new(task_queue.clone(), starter.get_wf_id().to_owned()).build(),
|
|
1139
|
+
)
|
|
1140
|
+
.await
|
|
1141
|
+
.unwrap();
|
|
1142
|
+
|
|
1143
|
+
let wf_id = task_queue;
|
|
1144
|
+
let update = async {
|
|
1145
|
+
let res = handle
|
|
1146
|
+
.execute_update(
|
|
1147
|
+
WorkerRestartedInMiddleOfUpdateWf::do_update,
|
|
1148
|
+
(),
|
|
1149
|
+
WorkflowExecuteUpdateOptions::default(),
|
|
1150
|
+
)
|
|
1151
|
+
.await;
|
|
1152
|
+
assert!(res.is_ok());
|
|
1153
|
+
handle
|
|
1154
|
+
.signal(
|
|
1155
|
+
WorkerRestartedInMiddleOfUpdateWf::done_signal,
|
|
1156
|
+
(),
|
|
1157
|
+
WorkflowSignalOptions::default(),
|
|
1041
1158
|
)
|
|
1042
1159
|
.await
|
|
1043
1160
|
.unwrap();
|
|
@@ -1051,10 +1168,19 @@ async fn worker_restarted_in_middle_of_update() {
|
|
|
1051
1168
|
// Allow it to start again, the second time
|
|
1052
1169
|
BARR.wait().await;
|
|
1053
1170
|
// Poke the workflow off the sticky queue to get it to complete faster than WFT timeout
|
|
1054
|
-
|
|
1055
|
-
.
|
|
1056
|
-
|
|
1057
|
-
|
|
1171
|
+
WorkflowService::reset_sticky_task_queue(
|
|
1172
|
+
&mut client.clone(),
|
|
1173
|
+
ResetStickyTaskQueueRequest {
|
|
1174
|
+
namespace: client.namespace(),
|
|
1175
|
+
execution: Some(WorkflowExecution {
|
|
1176
|
+
workflow_id: wf_id.clone(),
|
|
1177
|
+
run_id: "".to_string(),
|
|
1178
|
+
}),
|
|
1179
|
+
}
|
|
1180
|
+
.into_request(),
|
|
1181
|
+
)
|
|
1182
|
+
.await
|
|
1183
|
+
.unwrap();
|
|
1058
1184
|
};
|
|
1059
1185
|
let run = async {
|
|
1060
1186
|
// This run attempt will get shut down
|
|
@@ -1076,79 +1202,94 @@ async fn worker_restarted_in_middle_of_update() {
|
|
|
1076
1202
|
async fn update_after_empty_wft() {
|
|
1077
1203
|
let wf_name = "update_after_empty_wft";
|
|
1078
1204
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
1205
|
+
starter.sdk_config.register_activities(StdActivities);
|
|
1079
1206
|
let mut worker = starter.worker().await;
|
|
1080
|
-
let client = starter.get_client().await;
|
|
1081
1207
|
|
|
1082
1208
|
static ACT_STARTED: AtomicBool = AtomicBool::new(false);
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1209
|
+
|
|
1210
|
+
#[workflow]
|
|
1211
|
+
#[derive(Default)]
|
|
1212
|
+
struct UpdateAfterEmptyWftWf {
|
|
1213
|
+
signal_received: bool,
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
#[workflow_methods]
|
|
1217
|
+
impl UpdateAfterEmptyWftWf {
|
|
1218
|
+
#[run]
|
|
1219
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
1220
|
+
let sig_handle = async {
|
|
1221
|
+
ctx.wait_condition(|s| s.signal_received).await;
|
|
1222
|
+
ACT_STARTED.store(true, Ordering::Release);
|
|
1223
|
+
let _ = ctx
|
|
1224
|
+
.start_activity(
|
|
1225
|
+
StdActivities::echo,
|
|
1226
|
+
"hi!".to_string(),
|
|
1227
|
+
ActivityOptions {
|
|
1228
|
+
start_to_close_timeout: Some(Duration::from_secs(2)),
|
|
1229
|
+
..Default::default()
|
|
1230
|
+
},
|
|
1231
|
+
)
|
|
1232
|
+
.await;
|
|
1233
|
+
ACT_STARTED.store(false, Ordering::Release);
|
|
1234
|
+
};
|
|
1235
|
+
join!(sig_handle, async {
|
|
1236
|
+
ctx.timer(Duration::from_secs(2)).await;
|
|
1237
|
+
});
|
|
1238
|
+
Ok(())
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
#[signal]
|
|
1242
|
+
fn signal_handler(&mut self, _ctx: &mut SyncWorkflowContext<Self>, _: ()) {
|
|
1243
|
+
self.signal_received = true;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
#[update]
|
|
1247
|
+
async fn do_update(ctx: &mut WorkflowContext<Self>, _: ()) {
|
|
1248
|
+
if ACT_STARTED.load(Ordering::Acquire) {
|
|
1249
|
+
return;
|
|
1250
|
+
}
|
|
1251
|
+
let _ = ctx
|
|
1252
|
+
.start_activity(
|
|
1253
|
+
StdActivities::echo,
|
|
1254
|
+
"hi!".to_string(),
|
|
1255
|
+
ActivityOptions {
|
|
1095
1256
|
start_to_close_timeout: Some(Duration::from_secs(2)),
|
|
1096
1257
|
..Default::default()
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
let mut sig = ctx.make_signal_channel("signal");
|
|
1103
|
-
let sig_handle = async {
|
|
1104
|
-
sig.next().await;
|
|
1105
|
-
ACT_STARTED.store(true, Ordering::Release);
|
|
1106
|
-
ctx.activity(ActivityOptions {
|
|
1107
|
-
activity_type: "echo".to_string(),
|
|
1108
|
-
input: "hi!".as_json_payload().expect("serializes fine"),
|
|
1109
|
-
start_to_close_timeout: Some(Duration::from_secs(2)),
|
|
1110
|
-
..Default::default()
|
|
1111
|
-
})
|
|
1112
|
-
.await;
|
|
1113
|
-
ACT_STARTED.store(false, Ordering::Release);
|
|
1114
|
-
};
|
|
1115
|
-
join!(sig_handle, async {
|
|
1116
|
-
ctx.timer(Duration::from_secs(2)).await;
|
|
1117
|
-
});
|
|
1118
|
-
Ok(().into())
|
|
1119
|
-
});
|
|
1120
|
-
worker.register_activity("echo", |_ctx: ActContext, echo_me: String| async move {
|
|
1121
|
-
Ok(echo_me)
|
|
1122
|
-
});
|
|
1258
|
+
},
|
|
1259
|
+
)
|
|
1260
|
+
.await;
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1123
1263
|
|
|
1124
|
-
|
|
1264
|
+
worker.register_workflow::<UpdateAfterEmptyWftWf>();
|
|
1265
|
+
let task_queue = starter.get_task_queue().to_owned();
|
|
1266
|
+
let handle = worker
|
|
1267
|
+
.submit_workflow(
|
|
1268
|
+
UpdateAfterEmptyWftWf::run,
|
|
1269
|
+
(),
|
|
1270
|
+
WorkflowStartOptions::new(task_queue, starter.get_wf_id().to_owned()).build(),
|
|
1271
|
+
)
|
|
1272
|
+
.await
|
|
1273
|
+
.unwrap();
|
|
1125
1274
|
|
|
1126
|
-
let wf_id = starter.get_task_queue().to_string();
|
|
1127
1275
|
let update = async {
|
|
1128
|
-
|
|
1129
|
-
.
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
None,
|
|
1134
|
-
None,
|
|
1276
|
+
handle
|
|
1277
|
+
.signal(
|
|
1278
|
+
UpdateAfterEmptyWftWf::signal_handler,
|
|
1279
|
+
(),
|
|
1280
|
+
WorkflowSignalOptions::default(),
|
|
1135
1281
|
)
|
|
1136
1282
|
.await
|
|
1137
1283
|
.unwrap();
|
|
1138
1284
|
tokio::time::sleep(Duration::from_millis(500)).await;
|
|
1139
|
-
|
|
1140
|
-
.
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
WaitPolicy {
|
|
1145
|
-
lifecycle_stage: UpdateWorkflowExecutionLifecycleStage::Completed as i32,
|
|
1146
|
-
},
|
|
1147
|
-
[().as_json_payload().unwrap()].into_payloads(),
|
|
1285
|
+
handle
|
|
1286
|
+
.execute_update(
|
|
1287
|
+
UpdateAfterEmptyWftWf::do_update,
|
|
1288
|
+
(),
|
|
1289
|
+
WorkflowExecuteUpdateOptions::default(),
|
|
1148
1290
|
)
|
|
1149
1291
|
.await
|
|
1150
1292
|
.unwrap();
|
|
1151
|
-
assert!(res.outcome.unwrap().is_success());
|
|
1152
1293
|
};
|
|
1153
1294
|
let runner = async {
|
|
1154
1295
|
worker.run_until_done().await.unwrap();
|
|
@@ -1164,64 +1305,69 @@ async fn update_after_empty_wft() {
|
|
|
1164
1305
|
async fn update_lost_on_activity_mismatch() {
|
|
1165
1306
|
let wf_name = "update_lost_on_activity_mismatch";
|
|
1166
1307
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
1308
|
+
starter.sdk_config.register_activities(StdActivities);
|
|
1167
1309
|
let mut worker = starter.worker().await;
|
|
1168
|
-
let client = starter.get_client().await;
|
|
1169
1310
|
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1311
|
+
#[workflow]
|
|
1312
|
+
#[derive(Default)]
|
|
1313
|
+
struct UpdateLostOnActivityMismatchWf {
|
|
1314
|
+
can_run: usize,
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
#[workflow_methods]
|
|
1318
|
+
impl UpdateLostOnActivityMismatchWf {
|
|
1319
|
+
#[run]
|
|
1320
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
1321
|
+
ctx.state_mut(|s| s.can_run = 1);
|
|
1322
|
+
for _ in 1..=3 {
|
|
1323
|
+
ctx.wait_condition(|s| s.can_run > 0).await;
|
|
1324
|
+
let _ = ctx
|
|
1325
|
+
.start_activity(
|
|
1326
|
+
StdActivities::echo,
|
|
1327
|
+
"hi!".to_string(),
|
|
1328
|
+
ActivityOptions {
|
|
1329
|
+
start_to_close_timeout: Some(Duration::from_secs(2)),
|
|
1330
|
+
..Default::default()
|
|
1331
|
+
},
|
|
1332
|
+
)
|
|
1333
|
+
.await;
|
|
1334
|
+
ctx.state_mut(|s| s.can_run -= 1);
|
|
1335
|
+
}
|
|
1336
|
+
Ok(())
|
|
1195
1337
|
}
|
|
1196
|
-
Ok(().into())
|
|
1197
|
-
});
|
|
1198
|
-
worker.register_activity("echo", |_ctx: ActContext, echo_me: String| async move {
|
|
1199
|
-
Ok(echo_me)
|
|
1200
|
-
});
|
|
1201
1338
|
|
|
1202
|
-
|
|
1203
|
-
|
|
1339
|
+
#[update]
|
|
1340
|
+
fn do_update(&mut self, _ctx: &mut SyncWorkflowContext<Self>, _: ()) {
|
|
1341
|
+
self.can_run += 1;
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
worker.register_workflow::<UpdateLostOnActivityMismatchWf>();
|
|
1346
|
+
let core_worker = worker.core_worker();
|
|
1347
|
+
let task_queue = starter.get_task_queue().to_owned();
|
|
1348
|
+
let handle = worker
|
|
1349
|
+
.submit_workflow(
|
|
1350
|
+
UpdateLostOnActivityMismatchWf::run,
|
|
1351
|
+
(),
|
|
1352
|
+
WorkflowStartOptions::new(task_queue, starter.get_wf_id().to_owned()).build(),
|
|
1353
|
+
)
|
|
1354
|
+
.await
|
|
1355
|
+
.unwrap();
|
|
1204
1356
|
|
|
1205
|
-
let wf_id = starter.get_task_queue().to_string();
|
|
1206
1357
|
let update = async {
|
|
1207
1358
|
// Need time to get to condition
|
|
1208
1359
|
tokio::time::sleep(Duration::from_millis(200)).await;
|
|
1209
1360
|
// Evict wf
|
|
1210
|
-
core_worker.request_workflow_eviction(handle.
|
|
1361
|
+
core_worker.request_workflow_eviction(handle.run_id().unwrap());
|
|
1211
1362
|
for _ in 1..=2 {
|
|
1212
|
-
|
|
1213
|
-
.
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
WaitPolicy {
|
|
1218
|
-
lifecycle_stage: UpdateWorkflowExecutionLifecycleStage::Completed as i32,
|
|
1219
|
-
},
|
|
1220
|
-
[().as_json_payload().unwrap()].into_payloads(),
|
|
1363
|
+
handle
|
|
1364
|
+
.execute_update(
|
|
1365
|
+
UpdateLostOnActivityMismatchWf::do_update,
|
|
1366
|
+
(),
|
|
1367
|
+
WorkflowExecuteUpdateOptions::default(),
|
|
1221
1368
|
)
|
|
1222
1369
|
.await
|
|
1223
1370
|
.unwrap();
|
|
1224
|
-
assert!(res.outcome.unwrap().is_success());
|
|
1225
1371
|
}
|
|
1226
1372
|
};
|
|
1227
1373
|
let runner = async {
|