@temporalio/core-bridge 1.15.0 → 1.16.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 +172 -70
- package/lib/native.d.ts +1 -1
- package/package.json +2 -2
- 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 +41 -30
- package/sdk-core/Cargo.toml +3 -0
- package/sdk-core/README.md +15 -9
- 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} +280 -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} +1 -1
- package/sdk-core/crates/client/src/workflow_handle.rs +826 -0
- package/sdk-core/crates/common/Cargo.toml +61 -2
- 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/Makefile +2 -1
- package/sdk-core/crates/common/protos/api_upstream/buf.yaml +0 -3
- 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 +1166 -770
- package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv3.yaml +1243 -750
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/deployment/v1/message.proto +2 -2
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/workflow.proto +4 -3
- 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 +4 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/nexus/v1/message.proto +16 -1
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +64 -6
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +88 -33
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/nexus/nexus.proto +4 -2
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +4 -0
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +5 -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 +3 -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 +122 -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 +5 -7
- package/sdk-core/crates/common/src/telemetry/metrics/core.rs +125 -0
- package/sdk-core/crates/common/src/telemetry/metrics.rs +268 -223
- 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 +264 -4
- package/sdk-core/crates/common/src/worker.rs +68 -603
- 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 +757 -442
- package/sdk-core/crates/sdk/src/workflow_context/options.rs +45 -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 +57 -64
- package/sdk-core/crates/sdk-core/benches/workflow_replay_bench.rs +41 -35
- 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 +13 -15
- 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 +493 -26
- package/sdk-core/crates/sdk-core/src/core_tests/workflow_tasks.rs +4 -8
- package/sdk-core/crates/sdk-core/src/ephemeral_server/mod.rs +7 -7
- package/sdk-core/crates/sdk-core/src/histfetch.rs +20 -10
- package/sdk-core/crates/sdk-core/src/lib.rs +41 -111
- package/sdk-core/crates/sdk-core/src/pollers/mod.rs +4 -9
- package/sdk-core/crates/sdk-core/src/pollers/poll_buffer.rs +118 -19
- 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 +179 -196
- package/sdk-core/crates/sdk-core/src/telemetry/mod.rs +3 -280
- package/sdk-core/crates/sdk-core/src/test_help/integ_helpers.rs +6 -9
- package/sdk-core/crates/sdk-core/src/test_help/unit_helpers.rs +3 -6
- 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 +9 -5
- package/sdk-core/crates/sdk-core/src/worker/client.rs +103 -81
- package/sdk-core/crates/sdk-core/src/worker/heartbeat.rs +7 -11
- package/sdk-core/crates/sdk-core/src/worker/mod.rs +1124 -229
- package/sdk-core/crates/sdk-core/src/worker/nexus.rs +145 -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 +13 -13
- package/sdk-core/crates/sdk-core/src/worker/tuner.rs +28 -8
- package/sdk-core/crates/sdk-core/src/worker/workflow/driven_workflow.rs +9 -3
- 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 +19 -4
- package/sdk-core/crates/sdk-core/src/worker/workflow/managed_run.rs +14 -18
- package/sdk-core/crates/sdk-core/src/worker/workflow/mod.rs +4 -6
- 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 +241 -196
- package/sdk-core/crates/sdk-core/tests/common/workflows.rs +41 -28
- package/sdk-core/crates/sdk-core/tests/global_metric_tests.rs +3 -5
- package/sdk-core/crates/sdk-core/tests/heavy_tests/fuzzy_workflow.rs +73 -64
- package/sdk-core/crates/sdk-core/tests/heavy_tests.rs +298 -252
- 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 +16 -12
- package/sdk-core/crates/sdk-core/tests/integ_tests/heartbeat_tests.rs +48 -40
- package/sdk-core/crates/sdk-core/tests/integ_tests/metrics_tests.rs +327 -255
- 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 +147 -126
- 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 -453
- 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 +360 -231
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_tests.rs +248 -185
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_versioning_tests.rs +52 -43
- 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 +428 -315
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +82 -56
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +56 -28
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +364 -243
- 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 +101 -42
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +243 -147
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/eager.rs +98 -28
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +1475 -1036
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +73 -41
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +397 -238
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/patches.rs +414 -189
- 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 +154 -137
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/signals.rs +183 -105
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +85 -38
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/timers.rs +142 -40
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +73 -54
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests.rs +363 -226
- package/sdk-core/crates/sdk-core/tests/main.rs +17 -15
- package/sdk-core/crates/sdk-core/tests/manual_tests.rs +207 -152
- package/sdk-core/crates/sdk-core/tests/shared_tests/mod.rs +65 -34
- 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 +7 -1
- package/sdk-core/crates/sdk-core-c-bridge/include/temporal-sdk-core-c-bridge.h +14 -14
- package/sdk-core/crates/sdk-core-c-bridge/src/client.rs +83 -74
- package/sdk-core/crates/sdk-core-c-bridge/src/metric.rs +9 -14
- package/sdk-core/crates/sdk-core-c-bridge/src/runtime.rs +1 -2
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/context.rs +13 -13
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/mod.rs +6 -6
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/utils.rs +3 -4
- package/sdk-core/crates/sdk-core-c-bridge/src/worker.rs +62 -75
- package/sdk-core/rustfmt.toml +2 -1
- package/src/client.rs +205 -318
- package/src/metrics.rs +22 -30
- package/src/runtime.rs +4 -5
- package/src/worker.rs +16 -19
- package/ts/native.ts +1 -1
- 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/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,28 +1,27 @@
|
|
|
1
|
-
use crate::{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
},
|
|
6
|
-
integ_tests::activity_functions::echo,
|
|
1
|
+
use crate::common::{
|
|
2
|
+
ActivationAssertionsInterceptor, CoreWfStarter, INTEG_CLIENT_IDENTITY,
|
|
3
|
+
activity_functions::StdActivities, build_fake_sdk, eventually, init_core_and_create_wf,
|
|
4
|
+
mock_sdk, mock_sdk_cfg,
|
|
7
5
|
};
|
|
8
6
|
use anyhow::anyhow;
|
|
9
7
|
use assert_matches::assert_matches;
|
|
10
|
-
use futures_util::future::join_all;
|
|
11
8
|
use std::{
|
|
12
|
-
sync::
|
|
9
|
+
sync::{
|
|
10
|
+
Arc,
|
|
11
|
+
atomic::{AtomicBool, Ordering},
|
|
12
|
+
},
|
|
13
13
|
time::Duration,
|
|
14
14
|
};
|
|
15
15
|
use temporalio_client::{
|
|
16
|
-
|
|
16
|
+
ActivityIdentifier, UntypedWorkflow, WorkflowDescribeOptions, WorkflowStartOptions,
|
|
17
|
+
WorkflowTerminateOptions,
|
|
17
18
|
};
|
|
18
19
|
use temporalio_common::{
|
|
19
20
|
prost_dur,
|
|
20
21
|
protos::{
|
|
21
|
-
DEFAULT_ACTIVITY_TYPE, DEFAULT_WORKFLOW_TYPE,
|
|
22
|
-
canned_histories,
|
|
22
|
+
DEFAULT_ACTIVITY_TYPE, DEFAULT_WORKFLOW_TYPE, TestHistoryBuilder, canned_histories,
|
|
23
23
|
coresdk::{
|
|
24
|
-
ActivityHeartbeat, ActivityTaskCompletion,
|
|
25
|
-
IntoCompletion, IntoPayloadsExt,
|
|
24
|
+
ActivityHeartbeat, ActivityTaskCompletion, IntoCompletion, IntoPayloadsExt,
|
|
26
25
|
activity_result::{
|
|
27
26
|
self, ActivityExecutionResult, ActivityResolution, activity_resolution as act_res,
|
|
28
27
|
},
|
|
@@ -43,53 +42,115 @@ use temporalio_common::{
|
|
|
43
42
|
},
|
|
44
43
|
test_utils::schedule_activity_cmd,
|
|
45
44
|
},
|
|
46
|
-
worker::PollerBehavior,
|
|
47
45
|
};
|
|
46
|
+
use temporalio_macros::{activities, workflow, workflow_methods};
|
|
48
47
|
use temporalio_sdk::{
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
ActivityOptions, CancellableFuture, WorkflowContext, WorkflowResult, WorkflowTermination,
|
|
49
|
+
activities::{ActivityContext, ActivityError},
|
|
51
50
|
};
|
|
52
|
-
use temporalio_sdk_core::
|
|
53
|
-
|
|
51
|
+
use temporalio_sdk_core::{
|
|
52
|
+
PollerBehavior,
|
|
53
|
+
test_help::{
|
|
54
|
+
MockPollCfg, ResponseType, WorkerTestHelpers, drain_pollers_and_shutdown,
|
|
55
|
+
mock_worker_client,
|
|
56
|
+
},
|
|
54
57
|
};
|
|
55
58
|
use tokio::{join, sync::Semaphore, time::sleep};
|
|
56
59
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
#[workflow]
|
|
61
|
+
#[derive(Default)]
|
|
62
|
+
struct OneActivityWorkflow;
|
|
63
|
+
|
|
64
|
+
#[workflow_methods]
|
|
65
|
+
impl OneActivityWorkflow {
|
|
66
|
+
#[run]
|
|
67
|
+
async fn run(ctx: &mut WorkflowContext<Self>, input: String) -> WorkflowResult<String> {
|
|
68
|
+
let r = ctx
|
|
69
|
+
.start_activity(
|
|
70
|
+
StdActivities::echo,
|
|
71
|
+
input,
|
|
72
|
+
ActivityOptions {
|
|
73
|
+
start_to_close_timeout: Some(Duration::from_secs(5)),
|
|
74
|
+
..Default::default()
|
|
75
|
+
},
|
|
76
|
+
)
|
|
77
|
+
.await
|
|
78
|
+
.map_err(|e| anyhow!("{e}"))?;
|
|
79
|
+
Ok(r)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
#[workflow]
|
|
84
|
+
#[derive(Default)]
|
|
85
|
+
struct MultiArgActivityWorkflow;
|
|
86
|
+
|
|
87
|
+
#[workflow_methods]
|
|
88
|
+
impl MultiArgActivityWorkflow {
|
|
89
|
+
#[run]
|
|
90
|
+
async fn run(ctx: &mut WorkflowContext<Self>, input: String) -> WorkflowResult<String> {
|
|
91
|
+
let r = ctx
|
|
92
|
+
.start_activity(
|
|
93
|
+
StdActivities::concat,
|
|
94
|
+
(input, " world".to_string()),
|
|
95
|
+
ActivityOptions {
|
|
96
|
+
start_to_close_timeout: Some(Duration::from_secs(5)),
|
|
97
|
+
..Default::default()
|
|
98
|
+
},
|
|
99
|
+
)
|
|
100
|
+
.await
|
|
101
|
+
.map_err(|e| anyhow!("{e}"))?;
|
|
102
|
+
Ok(r)
|
|
103
|
+
}
|
|
66
104
|
}
|
|
67
105
|
|
|
68
106
|
#[tokio::test]
|
|
69
|
-
async fn
|
|
70
|
-
let wf_name =
|
|
107
|
+
async fn multi_arg_activity() {
|
|
108
|
+
let wf_name = MultiArgActivityWorkflow::name();
|
|
71
109
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
110
|
+
starter.sdk_config.register_activities(StdActivities);
|
|
111
|
+
starter
|
|
112
|
+
.sdk_config
|
|
113
|
+
.register_workflow::<MultiArgActivityWorkflow>();
|
|
72
114
|
let mut worker = starter.worker().await;
|
|
73
|
-
let client = starter.get_client().await;
|
|
74
|
-
worker.register_wf(wf_name.to_owned(), one_activity_wf);
|
|
75
|
-
worker.register_activity("echo_activity", echo);
|
|
76
115
|
|
|
77
|
-
let
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
116
|
+
let input = "hello".to_string();
|
|
117
|
+
let task_queue = starter.get_task_queue().to_owned();
|
|
118
|
+
let handle = worker
|
|
119
|
+
.submit_workflow(
|
|
120
|
+
MultiArgActivityWorkflow::run,
|
|
121
|
+
input,
|
|
122
|
+
WorkflowStartOptions::new(task_queue, wf_name.to_owned()).build(),
|
|
83
123
|
)
|
|
84
124
|
.await
|
|
85
125
|
.unwrap();
|
|
86
126
|
worker.run_until_done().await.unwrap();
|
|
87
|
-
let
|
|
88
|
-
|
|
89
|
-
|
|
127
|
+
let r = handle.get_result(Default::default()).await.unwrap();
|
|
128
|
+
assert_eq!(r, "hello world");
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
#[tokio::test]
|
|
132
|
+
async fn one_activity_only() {
|
|
133
|
+
let wf_name = OneActivityWorkflow::name();
|
|
134
|
+
let mut starter = CoreWfStarter::new(wf_name);
|
|
135
|
+
starter.sdk_config.register_activities(StdActivities);
|
|
136
|
+
starter
|
|
137
|
+
.sdk_config
|
|
138
|
+
.register_workflow::<OneActivityWorkflow>();
|
|
139
|
+
let mut worker = starter.worker().await;
|
|
140
|
+
|
|
141
|
+
let input = "hello from input!".to_string();
|
|
142
|
+
let task_queue = starter.get_task_queue().to_owned();
|
|
143
|
+
let handle = worker
|
|
144
|
+
.submit_workflow(
|
|
145
|
+
OneActivityWorkflow::run,
|
|
146
|
+
input.clone(),
|
|
147
|
+
WorkflowStartOptions::new(task_queue, wf_name.to_owned()).build(),
|
|
148
|
+
)
|
|
90
149
|
.await
|
|
91
150
|
.unwrap();
|
|
92
|
-
|
|
151
|
+
worker.run_until_done().await.unwrap();
|
|
152
|
+
let r = handle.get_result(Default::default()).await.unwrap();
|
|
153
|
+
assert_eq!(r, input);
|
|
93
154
|
}
|
|
94
155
|
|
|
95
156
|
#[tokio::test]
|
|
@@ -715,12 +776,10 @@ async fn async_activity_completion_workflow() {
|
|
|
715
776
|
starter
|
|
716
777
|
.get_client()
|
|
717
778
|
.await
|
|
718
|
-
.
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
}),
|
|
723
|
-
)
|
|
779
|
+
.get_async_activity_handle(ActivityIdentifier::TaskToken(task.task_token.into()))
|
|
780
|
+
.complete(Some(Payloads {
|
|
781
|
+
payloads: vec![response_payload.clone()],
|
|
782
|
+
}))
|
|
724
783
|
.await
|
|
725
784
|
.unwrap();
|
|
726
785
|
|
|
@@ -801,7 +860,8 @@ async fn activity_cancelled_after_heartbeat_times_out() {
|
|
|
801
860
|
starter
|
|
802
861
|
.get_client()
|
|
803
862
|
.await
|
|
804
|
-
.
|
|
863
|
+
.get_workflow_handle::<UntypedWorkflow>(task_q)
|
|
864
|
+
.terminate(WorkflowTerminateOptions::default())
|
|
805
865
|
.await
|
|
806
866
|
.unwrap();
|
|
807
867
|
}
|
|
@@ -861,10 +921,12 @@ async fn activity_heartbeat_not_flushed_on_success() {
|
|
|
861
921
|
|| async {
|
|
862
922
|
// Verify pending details has the flushed heartbeat
|
|
863
923
|
let details = client
|
|
864
|
-
.
|
|
924
|
+
.get_workflow_handle::<UntypedWorkflow>(starter.get_wf_id().to_string())
|
|
925
|
+
.describe(WorkflowDescribeOptions::default())
|
|
865
926
|
.await
|
|
866
927
|
.unwrap();
|
|
867
928
|
let last_deets = details
|
|
929
|
+
.raw_description
|
|
868
930
|
.pending_activities
|
|
869
931
|
.into_iter()
|
|
870
932
|
.find(|i| i.activity_id == activity_id)
|
|
@@ -880,222 +942,179 @@ async fn activity_heartbeat_not_flushed_on_success() {
|
|
|
880
942
|
.await
|
|
881
943
|
.unwrap();
|
|
882
944
|
client
|
|
883
|
-
.
|
|
945
|
+
.get_workflow_handle::<UntypedWorkflow>(task_q)
|
|
946
|
+
.terminate(WorkflowTerminateOptions::default())
|
|
884
947
|
.await
|
|
885
948
|
.unwrap();
|
|
886
949
|
drain_pollers_and_shutdown(&core).await;
|
|
887
950
|
}
|
|
888
951
|
|
|
952
|
+
#[workflow]
|
|
953
|
+
#[derive(Default)]
|
|
954
|
+
struct OneActivityAbandonCancelledBeforeStarted;
|
|
955
|
+
|
|
956
|
+
#[workflow_methods]
|
|
957
|
+
impl OneActivityAbandonCancelledBeforeStarted {
|
|
958
|
+
#[run]
|
|
959
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
960
|
+
let act_fut = ctx.start_activity(
|
|
961
|
+
StdActivities::delay,
|
|
962
|
+
Duration::from_secs(2),
|
|
963
|
+
ActivityOptions {
|
|
964
|
+
start_to_close_timeout: Some(Duration::from_secs(5)),
|
|
965
|
+
cancellation_type: ActivityCancellationType::Abandon,
|
|
966
|
+
..Default::default()
|
|
967
|
+
},
|
|
968
|
+
);
|
|
969
|
+
act_fut.cancel();
|
|
970
|
+
let _ = act_fut.await;
|
|
971
|
+
Ok(())
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
|
|
889
975
|
#[tokio::test]
|
|
890
976
|
async fn one_activity_abandon_cancelled_before_started() {
|
|
891
977
|
let wf_name = "one_activity_abandon_cancelled_before_started";
|
|
892
978
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
979
|
+
starter.sdk_config.register_activities(StdActivities);
|
|
980
|
+
starter
|
|
981
|
+
.sdk_config
|
|
982
|
+
.register_workflow::<OneActivityAbandonCancelledBeforeStarted>();
|
|
893
983
|
let mut worker = starter.worker().await;
|
|
894
|
-
let client = starter.get_client().await;
|
|
895
|
-
worker.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
|
|
896
|
-
let act_fut = ctx.activity(ActivityOptions {
|
|
897
|
-
activity_type: "echo_activity".to_string(),
|
|
898
|
-
start_to_close_timeout: Some(Duration::from_secs(5)),
|
|
899
|
-
input: "hi!".as_json_payload().expect("serializes fine"),
|
|
900
|
-
cancellation_type: ActivityCancellationType::Abandon,
|
|
901
|
-
..Default::default()
|
|
902
|
-
});
|
|
903
|
-
act_fut.cancel(&ctx);
|
|
904
|
-
act_fut.await;
|
|
905
|
-
Ok(().into())
|
|
906
|
-
});
|
|
907
|
-
worker.register_activity(
|
|
908
|
-
"echo_activity",
|
|
909
|
-
|_ctx: ActContext, echo_me: String| async move {
|
|
910
|
-
sleep(Duration::from_secs(2)).await;
|
|
911
|
-
Ok(echo_me)
|
|
912
|
-
},
|
|
913
|
-
);
|
|
914
984
|
|
|
915
|
-
let
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
985
|
+
let task_queue = starter.get_task_queue().to_owned();
|
|
986
|
+
let handle = worker
|
|
987
|
+
.submit_workflow(
|
|
988
|
+
OneActivityAbandonCancelledBeforeStarted::run,
|
|
989
|
+
(),
|
|
990
|
+
WorkflowStartOptions::new(task_queue, wf_name).build(),
|
|
921
991
|
)
|
|
922
992
|
.await
|
|
923
993
|
.unwrap();
|
|
924
994
|
worker.run_until_done().await.unwrap();
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
995
|
+
handle.get_result(Default::default()).await.unwrap();
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
#[workflow]
|
|
999
|
+
#[derive(Default)]
|
|
1000
|
+
struct OneActivityAbandonCancelledAfterComplete;
|
|
1001
|
+
|
|
1002
|
+
#[workflow_methods]
|
|
1003
|
+
impl OneActivityAbandonCancelledAfterComplete {
|
|
1004
|
+
#[run]
|
|
1005
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
1006
|
+
let act_fut = ctx.start_activity(
|
|
1007
|
+
StdActivities::delay,
|
|
1008
|
+
Duration::from_secs(2),
|
|
1009
|
+
ActivityOptions {
|
|
1010
|
+
start_to_close_timeout: Some(Duration::from_secs(5)),
|
|
1011
|
+
cancellation_type: ActivityCancellationType::Abandon,
|
|
1012
|
+
..Default::default()
|
|
1013
|
+
},
|
|
1014
|
+
);
|
|
1015
|
+
ctx.timer(Duration::from_secs(1)).await;
|
|
1016
|
+
act_fut.cancel();
|
|
1017
|
+
ctx.timer(Duration::from_secs(3)).await;
|
|
1018
|
+
let _ = act_fut.await;
|
|
1019
|
+
Ok(())
|
|
1020
|
+
}
|
|
931
1021
|
}
|
|
932
1022
|
|
|
933
1023
|
#[tokio::test]
|
|
934
1024
|
async fn one_activity_abandon_cancelled_after_complete() {
|
|
935
1025
|
let wf_name = "one_activity_abandon_cancelled_after_complete";
|
|
936
1026
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
1027
|
+
starter.sdk_config.register_activities(StdActivities);
|
|
1028
|
+
starter
|
|
1029
|
+
.sdk_config
|
|
1030
|
+
.register_workflow::<OneActivityAbandonCancelledAfterComplete>();
|
|
937
1031
|
let mut worker = starter.worker().await;
|
|
938
|
-
let client = starter.get_client().await;
|
|
939
|
-
worker.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
|
|
940
|
-
let act_fut = ctx.activity(ActivityOptions {
|
|
941
|
-
activity_type: "echo_activity".to_string(),
|
|
942
|
-
start_to_close_timeout: Some(Duration::from_secs(5)),
|
|
943
|
-
input: "hi!".as_json_payload().expect("serializes fine"),
|
|
944
|
-
cancellation_type: ActivityCancellationType::Abandon,
|
|
945
|
-
..Default::default()
|
|
946
|
-
});
|
|
947
|
-
ctx.timer(Duration::from_secs(1)).await;
|
|
948
|
-
act_fut.cancel(&ctx);
|
|
949
|
-
ctx.timer(Duration::from_secs(3)).await;
|
|
950
|
-
act_fut.await;
|
|
951
|
-
Ok(().into())
|
|
952
|
-
});
|
|
953
|
-
worker.register_activity(
|
|
954
|
-
"echo_activity",
|
|
955
|
-
|_ctx: ActContext, echo_me: String| async move {
|
|
956
|
-
sleep(Duration::from_secs(2)).await;
|
|
957
|
-
Ok(echo_me)
|
|
958
|
-
},
|
|
959
|
-
);
|
|
960
1032
|
|
|
961
|
-
let
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
1033
|
+
let task_queue = starter.get_task_queue().to_owned();
|
|
1034
|
+
let handle = worker
|
|
1035
|
+
.submit_workflow(
|
|
1036
|
+
OneActivityAbandonCancelledAfterComplete::run,
|
|
1037
|
+
(),
|
|
1038
|
+
WorkflowStartOptions::new(task_queue, wf_name).build(),
|
|
967
1039
|
)
|
|
968
1040
|
.await
|
|
969
1041
|
.unwrap();
|
|
970
1042
|
worker.run_until_done().await.unwrap();
|
|
971
|
-
|
|
972
|
-
let res = handle
|
|
973
|
-
.get_workflow_result(Default::default())
|
|
974
|
-
.await
|
|
975
|
-
.unwrap();
|
|
976
|
-
assert_matches!(res, WorkflowExecutionResult::Succeeded(_));
|
|
1043
|
+
handle.get_result(Default::default()).await.unwrap();
|
|
977
1044
|
}
|
|
978
1045
|
|
|
979
1046
|
#[tokio::test]
|
|
980
|
-
async fn
|
|
981
|
-
|
|
982
|
-
|
|
1047
|
+
async fn graceful_shutdown() {
|
|
1048
|
+
let wf_name = "graceful_shutdown";
|
|
1049
|
+
let mut starter = CoreWfStarter::new(wf_name);
|
|
1050
|
+
starter.sdk_config.graceful_shutdown_period = Some(Duration::from_millis(500));
|
|
983
1051
|
|
|
984
|
-
let
|
|
985
|
-
let
|
|
986
|
-
let mut worker = starter.worker().await;
|
|
987
|
-
let client = starter.get_client().await;
|
|
988
|
-
let async_response = "agence";
|
|
989
|
-
let shared_token: Arc<Mutex<Option<Vec<u8>>>> = Arc::new(Mutex::new(None));
|
|
990
|
-
worker.register_wf(wf_name.clone(), move |ctx: WfContext| async move {
|
|
991
|
-
let activity_resolution = ctx
|
|
992
|
-
.activity(ActivityOptions {
|
|
993
|
-
activity_type: "complete_async_activity".to_string(),
|
|
994
|
-
input: "hi".as_json_payload().expect("serializes fine"),
|
|
995
|
-
start_to_close_timeout: Some(Duration::from_secs(30)),
|
|
996
|
-
..Default::default()
|
|
997
|
-
})
|
|
998
|
-
.await;
|
|
1052
|
+
let acts_started = Arc::new(Semaphore::const_new(0));
|
|
1053
|
+
let acts_done = Arc::new(Semaphore::const_new(0));
|
|
999
1054
|
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1055
|
+
struct SleeperActivities {
|
|
1056
|
+
acts_started: Arc<Semaphore>,
|
|
1057
|
+
acts_done: Arc<Semaphore>,
|
|
1058
|
+
}
|
|
1059
|
+
#[activities]
|
|
1060
|
+
impl SleeperActivities {
|
|
1061
|
+
#[activity]
|
|
1062
|
+
async fn sleeper(
|
|
1063
|
+
self: Arc<Self>,
|
|
1064
|
+
ctx: ActivityContext,
|
|
1065
|
+
_: String,
|
|
1066
|
+
) -> Result<(), ActivityError> {
|
|
1067
|
+
self.acts_started.add_permits(1);
|
|
1068
|
+
// just wait to be cancelled
|
|
1069
|
+
ctx.cancelled().await;
|
|
1070
|
+
self.acts_done.add_permits(1);
|
|
1071
|
+
Err(ActivityError::cancelled())
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1006
1074
|
|
|
1007
|
-
|
|
1008
|
-
|
|
1075
|
+
starter.sdk_config.register_activities(SleeperActivities {
|
|
1076
|
+
acts_started: acts_started.clone(),
|
|
1077
|
+
acts_done: acts_done.clone(),
|
|
1009
1078
|
});
|
|
1079
|
+
let mut worker = starter.worker().await;
|
|
1080
|
+
let client = starter.get_client().await;
|
|
1010
1081
|
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
move |ctx: ActContext, _: String| {
|
|
1015
|
-
let shared_token_ref = shared_token_ref.clone();
|
|
1016
|
-
async move {
|
|
1017
|
-
// set the `activity_task_token`
|
|
1018
|
-
let activity_info = ctx.get_info();
|
|
1019
|
-
let task_token = &activity_info.task_token;
|
|
1020
|
-
let mut shared = shared_token_ref.lock().await;
|
|
1021
|
-
*shared = Some(task_token.clone());
|
|
1022
|
-
Ok::<ActExitValue<()>, _>(ActExitValue::WillCompleteAsync)
|
|
1023
|
-
}
|
|
1024
|
-
},
|
|
1025
|
-
);
|
|
1082
|
+
#[workflow]
|
|
1083
|
+
#[derive(Default)]
|
|
1084
|
+
struct GracefulShutdownWorkflow;
|
|
1026
1085
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
let
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
Some(
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1086
|
+
#[workflow_methods]
|
|
1087
|
+
impl GracefulShutdownWorkflow {
|
|
1088
|
+
#[run]
|
|
1089
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
1090
|
+
let act_futs = (1..=10).map(|_| {
|
|
1091
|
+
ctx.start_activity(
|
|
1092
|
+
SleeperActivities::sleeper,
|
|
1093
|
+
"hi".to_string(),
|
|
1094
|
+
ActivityOptions {
|
|
1095
|
+
start_to_close_timeout: Some(Duration::from_secs(5)),
|
|
1096
|
+
retry_policy: Some(RetryPolicy {
|
|
1097
|
+
maximum_attempts: 1,
|
|
1098
|
+
..Default::default()
|
|
1099
|
+
}),
|
|
1100
|
+
cancellation_type: ActivityCancellationType::WaitCancellationCompleted,
|
|
1101
|
+
..Default::default()
|
|
1102
|
+
},
|
|
1103
|
+
)
|
|
1104
|
+
});
|
|
1105
|
+
temporalio_sdk::workflows::join_all(act_futs).await;
|
|
1106
|
+
Ok(())
|
|
1043
1107
|
}
|
|
1044
|
-
}
|
|
1108
|
+
}
|
|
1045
1109
|
|
|
1046
|
-
|
|
1047
|
-
.submit_wf(
|
|
1048
|
-
wf_name.to_owned(),
|
|
1049
|
-
wf_name.to_owned(),
|
|
1050
|
-
vec![],
|
|
1051
|
-
WorkflowOptions::default(),
|
|
1052
|
-
)
|
|
1053
|
-
.await
|
|
1054
|
-
.unwrap();
|
|
1055
|
-
|
|
1056
|
-
worker.run_until_done().await.unwrap();
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
|
-
#[tokio::test]
|
|
1060
|
-
async fn graceful_shutdown() {
|
|
1061
|
-
let wf_name = "graceful_shutdown";
|
|
1062
|
-
let mut starter = CoreWfStarter::new(wf_name);
|
|
1063
|
-
starter.worker_config.graceful_shutdown_period = Some(Duration::from_millis(500));
|
|
1064
|
-
let mut worker = starter.worker().await;
|
|
1065
|
-
let client = starter.get_client().await;
|
|
1066
|
-
worker.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
|
|
1067
|
-
let act_futs = (1..=10).map(|_| {
|
|
1068
|
-
ctx.activity(ActivityOptions {
|
|
1069
|
-
activity_type: "sleeper".to_string(),
|
|
1070
|
-
start_to_close_timeout: Some(Duration::from_secs(5)),
|
|
1071
|
-
retry_policy: Some(RetryPolicy {
|
|
1072
|
-
maximum_attempts: 1,
|
|
1073
|
-
..Default::default()
|
|
1074
|
-
}),
|
|
1075
|
-
cancellation_type: ActivityCancellationType::WaitCancellationCompleted,
|
|
1076
|
-
input: "hi".as_json_payload().unwrap(),
|
|
1077
|
-
..Default::default()
|
|
1078
|
-
})
|
|
1079
|
-
});
|
|
1080
|
-
join_all(act_futs).await;
|
|
1081
|
-
Ok(().into())
|
|
1082
|
-
});
|
|
1083
|
-
static ACTS_STARTED: Semaphore = Semaphore::const_new(0);
|
|
1084
|
-
static ACTS_DONE: Semaphore = Semaphore::const_new(0);
|
|
1085
|
-
worker.register_activity("sleeper", |ctx: ActContext, _: String| async move {
|
|
1086
|
-
ACTS_STARTED.add_permits(1);
|
|
1087
|
-
// just wait to be cancelled
|
|
1088
|
-
ctx.cancelled().await;
|
|
1089
|
-
ACTS_DONE.add_permits(1);
|
|
1090
|
-
Result::<(), _>::Err(ActivityError::cancelled())
|
|
1091
|
-
});
|
|
1110
|
+
worker.register_workflow::<GracefulShutdownWorkflow>();
|
|
1092
1111
|
|
|
1112
|
+
let task_queue = starter.get_task_queue().to_owned();
|
|
1093
1113
|
worker
|
|
1094
|
-
.
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
WorkflowOptions::default(),
|
|
1114
|
+
.submit_workflow(
|
|
1115
|
+
GracefulShutdownWorkflow::run,
|
|
1116
|
+
(),
|
|
1117
|
+
WorkflowStartOptions::new(task_queue, wf_name).build(),
|
|
1099
1118
|
)
|
|
1100
1119
|
.await
|
|
1101
1120
|
.unwrap();
|
|
@@ -1103,13 +1122,14 @@ async fn graceful_shutdown() {
|
|
|
1103
1122
|
let handle = worker.inner_mut().shutdown_handle();
|
|
1104
1123
|
let shutdowner = async {
|
|
1105
1124
|
// Wait for all acts to be started before initiating shutdown
|
|
1106
|
-
let _ =
|
|
1125
|
+
let _ = acts_started.acquire_many(10).await;
|
|
1107
1126
|
handle();
|
|
1108
1127
|
// Kill workflow once all acts are cancelled. This also ensures we actually see all the
|
|
1109
1128
|
// cancels, otherwise run_until_done will hang since the workflow won't complete.
|
|
1110
|
-
let _ =
|
|
1129
|
+
let _ = acts_done.acquire_many(10).await;
|
|
1111
1130
|
client
|
|
1112
|
-
.
|
|
1131
|
+
.get_workflow_handle::<UntypedWorkflow>(wf_name.to_owned())
|
|
1132
|
+
.terminate(WorkflowTerminateOptions::default())
|
|
1113
1133
|
.await
|
|
1114
1134
|
.unwrap();
|
|
1115
1135
|
};
|
|
@@ -1123,38 +1143,76 @@ async fn graceful_shutdown() {
|
|
|
1123
1143
|
async fn activity_can_be_cancelled_by_local_timeout() {
|
|
1124
1144
|
let wf_name = "activity_can_be_cancelled_by_local_timeout";
|
|
1125
1145
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
1126
|
-
starter
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
Ok(().into())
|
|
1143
|
-
});
|
|
1144
|
-
static WAS_CANCELLED: AtomicBool = AtomicBool::new(false);
|
|
1145
|
-
worker.register_activity(
|
|
1146
|
-
"echo_activity",
|
|
1147
|
-
|ctx: ActContext, echo_me: String| async move {
|
|
1146
|
+
starter
|
|
1147
|
+
.set_core_cfg_mutator(|m| m.local_timeout_buffer_for_activities = Duration::from_secs(0));
|
|
1148
|
+
|
|
1149
|
+
let was_cancelled = Arc::new(AtomicBool::new(false));
|
|
1150
|
+
|
|
1151
|
+
struct CancellableEchoActivities {
|
|
1152
|
+
was_cancelled: Arc<AtomicBool>,
|
|
1153
|
+
}
|
|
1154
|
+
#[activities]
|
|
1155
|
+
impl CancellableEchoActivities {
|
|
1156
|
+
#[activity]
|
|
1157
|
+
async fn cancellable_echo(
|
|
1158
|
+
self: Arc<Self>,
|
|
1159
|
+
ctx: ActivityContext,
|
|
1160
|
+
echo_me: String,
|
|
1161
|
+
) -> Result<String, ActivityError> {
|
|
1148
1162
|
// Doesn't heartbeat
|
|
1149
1163
|
ctx.cancelled().await;
|
|
1150
|
-
|
|
1164
|
+
self.was_cancelled.store(true, Ordering::Relaxed);
|
|
1151
1165
|
Ok(echo_me)
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1154
1168
|
|
|
1155
|
-
starter
|
|
1169
|
+
starter
|
|
1170
|
+
.sdk_config
|
|
1171
|
+
.register_activities(CancellableEchoActivities {
|
|
1172
|
+
was_cancelled: was_cancelled.clone(),
|
|
1173
|
+
});
|
|
1174
|
+
let mut worker = starter.worker().await;
|
|
1175
|
+
|
|
1176
|
+
#[workflow]
|
|
1177
|
+
#[derive(Default)]
|
|
1178
|
+
struct ActivityLocalTimeoutWorkflow;
|
|
1179
|
+
|
|
1180
|
+
#[workflow_methods]
|
|
1181
|
+
impl ActivityLocalTimeoutWorkflow {
|
|
1182
|
+
#[run]
|
|
1183
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
1184
|
+
let res = ctx
|
|
1185
|
+
.start_activity(
|
|
1186
|
+
CancellableEchoActivities::cancellable_echo,
|
|
1187
|
+
"hi!".to_string(),
|
|
1188
|
+
ActivityOptions {
|
|
1189
|
+
start_to_close_timeout: Some(Duration::from_secs(1)),
|
|
1190
|
+
retry_policy: Some(RetryPolicy {
|
|
1191
|
+
maximum_attempts: 1,
|
|
1192
|
+
..Default::default()
|
|
1193
|
+
}),
|
|
1194
|
+
..Default::default()
|
|
1195
|
+
},
|
|
1196
|
+
)
|
|
1197
|
+
.await;
|
|
1198
|
+
assert!(res.is_err_and(|e| e.is_timeout()));
|
|
1199
|
+
Ok(())
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
worker.register_workflow::<ActivityLocalTimeoutWorkflow>();
|
|
1204
|
+
|
|
1205
|
+
let task_queue = starter.get_task_queue().to_owned();
|
|
1206
|
+
worker
|
|
1207
|
+
.submit_workflow(
|
|
1208
|
+
ActivityLocalTimeoutWorkflow::run,
|
|
1209
|
+
(),
|
|
1210
|
+
WorkflowStartOptions::new(task_queue.clone(), task_queue).build(),
|
|
1211
|
+
)
|
|
1212
|
+
.await
|
|
1213
|
+
.unwrap();
|
|
1156
1214
|
worker.run_until_done().await.unwrap();
|
|
1157
|
-
assert!(
|
|
1215
|
+
assert!(was_cancelled.load(Ordering::Relaxed));
|
|
1158
1216
|
}
|
|
1159
1217
|
|
|
1160
1218
|
#[tokio::test]
|
|
@@ -1164,42 +1222,56 @@ async fn activity_can_be_cancelled_by_local_timeout() {
|
|
|
1164
1222
|
async fn long_activity_timeout_repro() {
|
|
1165
1223
|
let wf_name = "long_activity_timeout_repro";
|
|
1166
1224
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
1167
|
-
starter.
|
|
1225
|
+
starter.sdk_config.workflow_task_poller_behavior = PollerBehavior::Autoscaling {
|
|
1168
1226
|
minimum: 1,
|
|
1169
1227
|
maximum: 10,
|
|
1170
1228
|
initial: 5,
|
|
1171
1229
|
};
|
|
1172
|
-
starter.
|
|
1230
|
+
starter.sdk_config.activity_task_poller_behavior = PollerBehavior::Autoscaling {
|
|
1173
1231
|
minimum: 1,
|
|
1174
1232
|
maximum: 10,
|
|
1175
1233
|
initial: 5,
|
|
1176
1234
|
};
|
|
1177
|
-
starter
|
|
1235
|
+
starter
|
|
1236
|
+
.set_core_cfg_mutator(|m| m.local_timeout_buffer_for_activities = Duration::from_secs(0));
|
|
1237
|
+
starter.sdk_config.register_activities(StdActivities);
|
|
1178
1238
|
let mut worker = starter.worker().await;
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1239
|
+
|
|
1240
|
+
#[workflow]
|
|
1241
|
+
#[derive(Default)]
|
|
1242
|
+
struct LongActivityTimeoutReproWorkflow;
|
|
1243
|
+
|
|
1244
|
+
#[workflow_methods]
|
|
1245
|
+
impl LongActivityTimeoutReproWorkflow {
|
|
1246
|
+
#[run]
|
|
1247
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
1248
|
+
let mut iter = 1;
|
|
1249
|
+
loop {
|
|
1250
|
+
let res = ctx
|
|
1251
|
+
.start_activity(
|
|
1252
|
+
StdActivities::echo,
|
|
1253
|
+
"hi!".to_string(),
|
|
1254
|
+
ActivityOptions {
|
|
1255
|
+
start_to_close_timeout: Some(Duration::from_secs(1)),
|
|
1256
|
+
retry_policy: Some(RetryPolicy {
|
|
1257
|
+
maximum_attempts: 1,
|
|
1258
|
+
..Default::default()
|
|
1259
|
+
}),
|
|
1260
|
+
..Default::default()
|
|
1261
|
+
},
|
|
1262
|
+
)
|
|
1263
|
+
.await;
|
|
1264
|
+
assert!(res.is_ok());
|
|
1265
|
+
ctx.timer(Duration::from_secs(60 * 3)).await;
|
|
1266
|
+
iter += 1;
|
|
1267
|
+
if iter > 5000 {
|
|
1268
|
+
return Err(WorkflowTermination::continue_as_new(Default::default()));
|
|
1269
|
+
}
|
|
1199
1270
|
}
|
|
1200
1271
|
}
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
worker.register_workflow::<LongActivityTimeoutReproWorkflow>();
|
|
1203
1275
|
|
|
1204
1276
|
starter.start_with_worker(wf_name, &mut worker).await;
|
|
1205
1277
|
worker.run_until_done().await.unwrap();
|
|
@@ -1235,21 +1307,36 @@ async fn pass_activity_summary_to_metadata() {
|
|
|
1235
1307
|
});
|
|
1236
1308
|
|
|
1237
1309
|
let mut worker = mock_sdk_cfg(mock_cfg, |_| {});
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1310
|
+
|
|
1311
|
+
#[workflow]
|
|
1312
|
+
#[derive(Default)]
|
|
1313
|
+
struct ActivitySummaryWorkflow;
|
|
1314
|
+
|
|
1315
|
+
#[workflow_methods]
|
|
1316
|
+
impl ActivitySummaryWorkflow {
|
|
1317
|
+
#[run(name = DEFAULT_WORKFLOW_TYPE)]
|
|
1318
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
1319
|
+
ctx.start_activity(
|
|
1320
|
+
StdActivities::default,
|
|
1321
|
+
(),
|
|
1322
|
+
ActivityOptions {
|
|
1323
|
+
summary: Some("activity summary".to_string()),
|
|
1324
|
+
..Default::default()
|
|
1325
|
+
},
|
|
1326
|
+
)
|
|
1327
|
+
.await
|
|
1328
|
+
.map_err(|e| anyhow!("{e}"))?;
|
|
1329
|
+
Ok(())
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
worker.register_workflow::<ActivitySummaryWorkflow>();
|
|
1334
|
+
let task_queue = worker.inner_mut().task_queue().to_owned();
|
|
1247
1335
|
worker
|
|
1248
1336
|
.submit_wf(
|
|
1249
|
-
wf_id.to_owned(),
|
|
1250
1337
|
wf_type.to_owned(),
|
|
1251
1338
|
vec![],
|
|
1252
|
-
|
|
1339
|
+
WorkflowStartOptions::new(task_queue, wf_id.to_owned()).build(),
|
|
1253
1340
|
)
|
|
1254
1341
|
.await
|
|
1255
1342
|
.unwrap();
|
|
@@ -1284,42 +1371,68 @@ async fn abandoned_activities_ignore_start_and_complete(hist_batches: &'static [
|
|
|
1284
1371
|
let mock = mock_worker_client();
|
|
1285
1372
|
let mut worker = mock_sdk(MockPollCfg::from_resp_batches(wfid, t, hist_batches, mock));
|
|
1286
1373
|
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
ctx
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1374
|
+
#[workflow]
|
|
1375
|
+
#[derive(Default)]
|
|
1376
|
+
struct AbandonedActivitiesWorkflow;
|
|
1377
|
+
|
|
1378
|
+
#[workflow_methods]
|
|
1379
|
+
impl AbandonedActivitiesWorkflow {
|
|
1380
|
+
#[run(name = DEFAULT_WORKFLOW_TYPE)]
|
|
1381
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
1382
|
+
let act_fut = ctx.start_activity(
|
|
1383
|
+
StdActivities::default,
|
|
1384
|
+
(),
|
|
1385
|
+
ActivityOptions {
|
|
1386
|
+
start_to_close_timeout: Some(Duration::from_secs(5)),
|
|
1387
|
+
cancellation_type: ActivityCancellationType::Abandon,
|
|
1388
|
+
..Default::default()
|
|
1389
|
+
},
|
|
1390
|
+
);
|
|
1391
|
+
ctx.timer(Duration::from_secs(1)).await;
|
|
1392
|
+
act_fut.cancel();
|
|
1393
|
+
ctx.timer(Duration::from_secs(3)).await;
|
|
1394
|
+
let _ = act_fut.await;
|
|
1395
|
+
Ok(())
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
worker.register_workflow::<AbandonedActivitiesWorkflow>();
|
|
1400
|
+
let task_queue = worker.inner_mut().task_queue().to_owned();
|
|
1300
1401
|
worker
|
|
1301
|
-
.submit_wf(
|
|
1402
|
+
.submit_wf(
|
|
1403
|
+
wf_type,
|
|
1404
|
+
vec![],
|
|
1405
|
+
WorkflowStartOptions::new(task_queue, wfid).build(),
|
|
1406
|
+
)
|
|
1302
1407
|
.await
|
|
1303
1408
|
.unwrap();
|
|
1304
1409
|
worker.run_until_done().await.unwrap();
|
|
1305
1410
|
}
|
|
1306
1411
|
|
|
1412
|
+
#[workflow]
|
|
1413
|
+
#[derive(Default)]
|
|
1414
|
+
struct ImmediateActivityCancelationWorkflow;
|
|
1415
|
+
|
|
1416
|
+
#[workflow_methods]
|
|
1417
|
+
impl ImmediateActivityCancelationWorkflow {
|
|
1418
|
+
#[run(name = DEFAULT_WORKFLOW_TYPE)]
|
|
1419
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
1420
|
+
let cancel_activity_future =
|
|
1421
|
+
ctx.start_activity(StdActivities::default, (), ActivityOptions::default());
|
|
1422
|
+
cancel_activity_future.cancel();
|
|
1423
|
+
let _ = cancel_activity_future.await;
|
|
1424
|
+
Ok(())
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1307
1428
|
#[tokio::test]
|
|
1308
1429
|
async fn immediate_activity_cancelation() {
|
|
1309
|
-
let func = WorkflowFunction::new(|ctx: WfContext| async move {
|
|
1310
|
-
let cancel_activity_future = ctx.activity(ActivityOptions::default());
|
|
1311
|
-
// Immediately cancel the activity
|
|
1312
|
-
cancel_activity_future.cancel(&ctx);
|
|
1313
|
-
cancel_activity_future.await;
|
|
1314
|
-
Ok(().into())
|
|
1315
|
-
});
|
|
1316
|
-
|
|
1317
1430
|
let mut t = TestHistoryBuilder::default();
|
|
1318
1431
|
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
1319
1432
|
t.add_full_wf_task();
|
|
1320
1433
|
t.add_workflow_execution_completed();
|
|
1321
1434
|
let mut worker = build_fake_sdk(MockPollCfg::from_resps(t, [ResponseType::AllHistory]));
|
|
1322
|
-
worker.
|
|
1435
|
+
worker.register_workflow::<ImmediateActivityCancelationWorkflow>();
|
|
1323
1436
|
|
|
1324
1437
|
let mut aai = ActivationAssertionsInterceptor::default();
|
|
1325
1438
|
aai.then(|a| {
|