@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,7 +1,8 @@
|
|
|
1
|
-
use crate::common::{
|
|
1
|
+
use crate::common::{
|
|
2
|
+
ANY_PORT, CoreWfStarter, activity_functions::StdActivities, eventually, get_integ_telem_options,
|
|
3
|
+
};
|
|
2
4
|
use anyhow::anyhow;
|
|
3
5
|
use crossbeam_utils::atomic::AtomicCell;
|
|
4
|
-
use futures_util::StreamExt;
|
|
5
6
|
use prost_types::{Duration as PbDuration, Timestamp};
|
|
6
7
|
use std::{
|
|
7
8
|
collections::HashSet,
|
|
@@ -13,12 +14,13 @@ use std::{
|
|
|
13
14
|
time::{Duration, SystemTime, UNIX_EPOCH},
|
|
14
15
|
};
|
|
15
16
|
use temporalio_client::{
|
|
16
|
-
Client, NamespacedClient,
|
|
17
|
+
Client, NamespacedClient, WorkflowExecutionInfo, WorkflowSignalOptions, WorkflowStartOptions,
|
|
18
|
+
grpc::WorkflowService,
|
|
17
19
|
};
|
|
18
20
|
use temporalio_common::{
|
|
19
21
|
prost_dur,
|
|
20
22
|
protos::{
|
|
21
|
-
coresdk::
|
|
23
|
+
coresdk::AsJsonPayloadExt,
|
|
22
24
|
temporal::api::{
|
|
23
25
|
common::v1::RetryPolicy,
|
|
24
26
|
enums::v1::WorkerStatus,
|
|
@@ -27,14 +29,18 @@ use temporalio_common::{
|
|
|
27
29
|
},
|
|
28
30
|
},
|
|
29
31
|
telemetry::{
|
|
30
|
-
|
|
32
|
+
OtelCollectorOptions, PrometheusExporterOptions, TelemetryOptions,
|
|
33
|
+
build_otlp_metric_exporter, start_prometheus_metric_exporter,
|
|
31
34
|
},
|
|
32
|
-
worker::PollerBehavior,
|
|
33
35
|
};
|
|
34
|
-
use
|
|
36
|
+
use temporalio_macros::{activities, workflow, workflow_methods};
|
|
37
|
+
use temporalio_sdk::{
|
|
38
|
+
ActivityOptions, SyncWorkflowContext, WorkflowContext, WorkflowResult,
|
|
39
|
+
activities::{ActivityContext, ActivityError},
|
|
40
|
+
};
|
|
35
41
|
use temporalio_sdk_core::{
|
|
36
|
-
CoreRuntime, ResourceBasedTuner, ResourceSlotOptions,
|
|
37
|
-
|
|
42
|
+
CoreRuntime, PollerBehavior, ResourceBasedTuner, ResourceSlotOptions, RuntimeOptions,
|
|
43
|
+
TunerHolder,
|
|
38
44
|
};
|
|
39
45
|
use tokio::{sync::Notify, time::sleep};
|
|
40
46
|
use tonic::IntoRequest;
|
|
@@ -54,8 +60,8 @@ fn within_duration(dur: PbDuration, threshold: Duration) -> bool {
|
|
|
54
60
|
}
|
|
55
61
|
|
|
56
62
|
fn new_no_metrics_starter(wf_name: &str) -> CoreWfStarter {
|
|
57
|
-
let runtimeopts =
|
|
58
|
-
.telemetry_options(
|
|
63
|
+
let runtimeopts = RuntimeOptions::builder()
|
|
64
|
+
.telemetry_options(TelemetryOptions::builder().build())
|
|
59
65
|
.heartbeat_interval(Some(Duration::from_secs(1)))
|
|
60
66
|
.build()
|
|
61
67
|
.unwrap();
|
|
@@ -66,11 +72,8 @@ fn to_system_time(ts: Timestamp) -> SystemTime {
|
|
|
66
72
|
UNIX_EPOCH + Duration::new(ts.seconds as u64, ts.nanos as u32)
|
|
67
73
|
}
|
|
68
74
|
|
|
69
|
-
async fn list_worker_heartbeats(
|
|
70
|
-
client
|
|
71
|
-
query: impl Into<String>,
|
|
72
|
-
) -> Vec<WorkerHeartbeat> {
|
|
73
|
-
let mut raw_client = client.as_ref().clone();
|
|
75
|
+
async fn list_worker_heartbeats(client: &Client, query: impl Into<String>) -> Vec<WorkerHeartbeat> {
|
|
76
|
+
let mut raw_client = client.clone();
|
|
74
77
|
WorkflowService::list_workers(
|
|
75
78
|
&mut raw_client,
|
|
76
79
|
ListWorkersRequest {
|
|
@@ -99,11 +102,11 @@ async fn docker_worker_heartbeat_basic(#[values("otel", "prom", "no_metrics")] b
|
|
|
99
102
|
return;
|
|
100
103
|
}
|
|
101
104
|
let telemopts = if backing == "no_metrics" {
|
|
102
|
-
|
|
105
|
+
TelemetryOptions::builder().build()
|
|
103
106
|
} else {
|
|
104
107
|
get_integ_telem_options()
|
|
105
108
|
};
|
|
106
|
-
let runtimeopts =
|
|
109
|
+
let runtimeopts = RuntimeOptions::builder()
|
|
107
110
|
.telemetry_options(telemopts)
|
|
108
111
|
.heartbeat_interval(Some(Duration::from_secs(1)))
|
|
109
112
|
.build()
|
|
@@ -114,15 +117,15 @@ async fn docker_worker_heartbeat_basic(#[values("otel", "prom", "no_metrics")] b
|
|
|
114
117
|
let url = Some("grpc://localhost:4317")
|
|
115
118
|
.map(|x| x.parse::<Url>().unwrap())
|
|
116
119
|
.unwrap();
|
|
117
|
-
let
|
|
118
|
-
let opts = opts_build.url(url).build()
|
|
120
|
+
let opts_build = OtelCollectorOptions::builder();
|
|
121
|
+
let opts = opts_build.url(url).build();
|
|
119
122
|
rt.telemetry_mut()
|
|
120
123
|
.attach_late_init_metrics(Arc::new(build_otlp_metric_exporter(opts).unwrap()));
|
|
121
124
|
}
|
|
122
125
|
"prom" => {
|
|
123
|
-
let
|
|
124
|
-
|
|
125
|
-
let opts = opts_build.build()
|
|
126
|
+
let opts_build =
|
|
127
|
+
PrometheusExporterOptions::builder().socket_addr(ANY_PORT.parse().unwrap());
|
|
128
|
+
let opts = opts_build.build();
|
|
126
129
|
rt.telemetry_mut()
|
|
127
130
|
.attach_late_init_metrics(start_prometheus_metric_exporter(opts).unwrap().meter);
|
|
128
131
|
}
|
|
@@ -131,56 +134,77 @@ async fn docker_worker_heartbeat_basic(#[values("otel", "prom", "no_metrics")] b
|
|
|
131
134
|
}
|
|
132
135
|
let wf_name = format!("worker_heartbeat_basic_{backing}");
|
|
133
136
|
let mut starter = CoreWfStarter::new_with_runtime(&wf_name, rt);
|
|
134
|
-
starter
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
]
|
|
150
|
-
.into_iter()
|
|
151
|
-
.collect::<HashSet<_>>(),
|
|
152
|
-
);
|
|
153
|
-
let mut worker = starter.worker().await;
|
|
154
|
-
let worker_instance_key = worker.worker_instance_key();
|
|
155
|
-
|
|
156
|
-
worker.register_wf(wf_name.to_string(), |ctx: WfContext| async move {
|
|
157
|
-
ctx.activity(ActivityOptions {
|
|
158
|
-
activity_type: "pass_fail_act".to_string(),
|
|
159
|
-
input: "pass".as_json_payload().expect("serializes fine"),
|
|
160
|
-
start_to_close_timeout: Some(Duration::from_secs(5)),
|
|
161
|
-
..Default::default()
|
|
162
|
-
})
|
|
163
|
-
.await;
|
|
164
|
-
Ok(().into())
|
|
137
|
+
starter.sdk_config.max_cached_workflows = 5_usize;
|
|
138
|
+
starter.sdk_config.tuner = Arc::new(TunerHolder::fixed_size(5, 5, 100, 0));
|
|
139
|
+
starter.set_core_cfg_mutator(|c| {
|
|
140
|
+
c.plugins = vec![
|
|
141
|
+
PluginInfo {
|
|
142
|
+
name: "plugin1".to_string(),
|
|
143
|
+
version: "1".to_string(),
|
|
144
|
+
},
|
|
145
|
+
PluginInfo {
|
|
146
|
+
name: "plugin2".to_string(),
|
|
147
|
+
version: "2".to_string(),
|
|
148
|
+
},
|
|
149
|
+
]
|
|
150
|
+
.into_iter()
|
|
151
|
+
.collect();
|
|
165
152
|
});
|
|
166
|
-
|
|
167
153
|
let acts_started = Arc::new(Notify::new());
|
|
168
154
|
let acts_done = Arc::new(Notify::new());
|
|
169
155
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
156
|
+
struct NotifyActivities {
|
|
157
|
+
acts_started: Arc<Notify>,
|
|
158
|
+
acts_done: Arc<Notify>,
|
|
159
|
+
}
|
|
160
|
+
#[activities]
|
|
161
|
+
impl NotifyActivities {
|
|
162
|
+
#[activity]
|
|
163
|
+
async fn pass_fail_act(
|
|
164
|
+
self: Arc<Self>,
|
|
165
|
+
_ctx: ActivityContext,
|
|
166
|
+
i: String,
|
|
167
|
+
) -> Result<String, ActivityError> {
|
|
168
|
+
self.acts_started.notify_one();
|
|
169
|
+
self.acts_done.notified().await;
|
|
178
170
|
Ok(i)
|
|
179
171
|
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
starter.sdk_config.register_activities(NotifyActivities {
|
|
175
|
+
acts_started: acts_started.clone(),
|
|
176
|
+
acts_done: acts_done.clone(),
|
|
180
177
|
});
|
|
178
|
+
let mut worker = starter.worker().await;
|
|
179
|
+
let worker_instance_key = worker.worker_instance_key();
|
|
180
|
+
|
|
181
|
+
#[workflow]
|
|
182
|
+
#[derive(Default)]
|
|
183
|
+
struct HeartbeatBasicWf;
|
|
184
|
+
|
|
185
|
+
#[workflow_methods]
|
|
186
|
+
impl HeartbeatBasicWf {
|
|
187
|
+
#[run]
|
|
188
|
+
#[allow(dead_code)]
|
|
189
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
190
|
+
let _ = ctx
|
|
191
|
+
.start_activity(
|
|
192
|
+
NotifyActivities::pass_fail_act,
|
|
193
|
+
"pass".to_string(),
|
|
194
|
+
ActivityOptions {
|
|
195
|
+
start_to_close_timeout: Some(Duration::from_secs(5)),
|
|
196
|
+
..Default::default()
|
|
197
|
+
},
|
|
198
|
+
)
|
|
199
|
+
.await;
|
|
200
|
+
Ok(())
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
worker.register_workflow::<HeartbeatBasicWf>();
|
|
181
205
|
|
|
182
206
|
starter
|
|
183
|
-
.start_with_worker(
|
|
207
|
+
.start_with_worker(HeartbeatBasicWf::name(), &mut worker)
|
|
184
208
|
.await;
|
|
185
209
|
|
|
186
210
|
let start_time = AtomicCell::new(None);
|
|
@@ -191,7 +215,7 @@ async fn docker_worker_heartbeat_basic(#[values("otel", "prom", "no_metrics")] b
|
|
|
191
215
|
tokio::time::sleep(Duration::from_millis(1500)).await;
|
|
192
216
|
acts_started.notified().await;
|
|
193
217
|
let client = starter.get_client().await;
|
|
194
|
-
let mut raw_client =
|
|
218
|
+
let mut raw_client = client.clone();
|
|
195
219
|
let workers_list = WorkflowService::list_workers(
|
|
196
220
|
&mut raw_client,
|
|
197
221
|
ListWorkersRequest {
|
|
@@ -231,7 +255,7 @@ async fn docker_worker_heartbeat_basic(#[values("otel", "prom", "no_metrics")] b
|
|
|
231
255
|
tokio::join!(test_fut, runner);
|
|
232
256
|
|
|
233
257
|
let client = starter.get_client().await;
|
|
234
|
-
let mut raw_client =
|
|
258
|
+
let mut raw_client = client.clone();
|
|
235
259
|
let workers_list = WorkflowService::list_workers(
|
|
236
260
|
&mut raw_client,
|
|
237
261
|
ListWorkersRequest {
|
|
@@ -269,7 +293,7 @@ async fn docker_worker_heartbeat_tuner() {
|
|
|
269
293
|
if env::var("DOCKER_PROMETHEUS_RUNNING").is_err() {
|
|
270
294
|
return;
|
|
271
295
|
}
|
|
272
|
-
let runtimeopts =
|
|
296
|
+
let runtimeopts = RuntimeOptions::builder()
|
|
273
297
|
.telemetry_options(get_integ_telem_options())
|
|
274
298
|
.heartbeat_interval(Some(Duration::from_secs(1)))
|
|
275
299
|
.build()
|
|
@@ -279,8 +303,8 @@ async fn docker_worker_heartbeat_tuner() {
|
|
|
279
303
|
let url = Some("grpc://localhost:4317")
|
|
280
304
|
.map(|x| x.parse::<Url>().unwrap())
|
|
281
305
|
.unwrap();
|
|
282
|
-
let
|
|
283
|
-
let opts = opts_build.url(url).build()
|
|
306
|
+
let opts_build = OtelCollectorOptions::builder();
|
|
307
|
+
let opts = opts_build.url(url).build();
|
|
284
308
|
|
|
285
309
|
rt.telemetry_mut()
|
|
286
310
|
.attach_late_init_metrics(Arc::new(build_otlp_metric_exporter(opts).unwrap()));
|
|
@@ -290,43 +314,53 @@ async fn docker_worker_heartbeat_tuner() {
|
|
|
290
314
|
tuner
|
|
291
315
|
.with_workflow_slots_options(ResourceSlotOptions::new(2, 10, Duration::from_millis(0)))
|
|
292
316
|
.with_activity_slots_options(ResourceSlotOptions::new(5, 10, Duration::from_millis(50)));
|
|
293
|
-
starter
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
.clear_max_outstanding_opts()
|
|
306
|
-
.tuner(Arc::new(tuner));
|
|
317
|
+
starter.sdk_config.workflow_task_poller_behavior = PollerBehavior::Autoscaling {
|
|
318
|
+
minimum: 1,
|
|
319
|
+
maximum: 200,
|
|
320
|
+
initial: 5,
|
|
321
|
+
};
|
|
322
|
+
starter.sdk_config.nexus_task_poller_behavior = PollerBehavior::Autoscaling {
|
|
323
|
+
minimum: 1,
|
|
324
|
+
maximum: 200,
|
|
325
|
+
initial: 5,
|
|
326
|
+
};
|
|
327
|
+
starter.sdk_config.tuner = Arc::new(tuner);
|
|
328
|
+
starter.sdk_config.register_activities(StdActivities);
|
|
307
329
|
let mut worker = starter.worker().await;
|
|
308
330
|
let worker_instance_key = worker.worker_instance_key();
|
|
309
331
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
332
|
+
#[workflow]
|
|
333
|
+
#[derive(Default)]
|
|
334
|
+
struct HeartbeatTunerWf;
|
|
335
|
+
|
|
336
|
+
#[workflow_methods]
|
|
337
|
+
impl HeartbeatTunerWf {
|
|
338
|
+
#[run]
|
|
339
|
+
#[allow(dead_code)]
|
|
340
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
341
|
+
let _ = ctx
|
|
342
|
+
.start_activity(
|
|
343
|
+
StdActivities::echo,
|
|
344
|
+
"pass".to_string(),
|
|
345
|
+
ActivityOptions {
|
|
346
|
+
start_to_close_timeout: Some(Duration::from_secs(1)),
|
|
347
|
+
..Default::default()
|
|
348
|
+
},
|
|
349
|
+
)
|
|
350
|
+
.await;
|
|
351
|
+
Ok(())
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
worker.register_workflow::<HeartbeatTunerWf>();
|
|
324
356
|
|
|
325
|
-
starter
|
|
357
|
+
starter
|
|
358
|
+
.start_with_worker(HeartbeatTunerWf::name(), &mut worker)
|
|
359
|
+
.await;
|
|
326
360
|
worker.run_until_done().await.unwrap();
|
|
327
361
|
|
|
328
362
|
let client = starter.get_client().await;
|
|
329
|
-
let mut raw_client =
|
|
363
|
+
let mut raw_client = client.clone();
|
|
330
364
|
let workers_list = WorkflowService::list_workers(
|
|
331
365
|
&mut raw_client,
|
|
332
366
|
ListWorkersRequest {
|
|
@@ -456,7 +490,7 @@ fn after_shutdown_checks(
|
|
|
456
490
|
assert_eq!(heartbeat.worker_identity, "integ_tester");
|
|
457
491
|
let host_info = heartbeat.host_info.clone().unwrap();
|
|
458
492
|
assert!(!host_info.host_name.is_empty());
|
|
459
|
-
assert!(!host_info.
|
|
493
|
+
assert!(!host_info.worker_grouping_key.is_empty());
|
|
460
494
|
assert!(!host_info.process_id.is_empty());
|
|
461
495
|
assert!(host_info.current_host_cpu_usage >= 0.0);
|
|
462
496
|
assert!(host_info.current_host_mem_usage >= 0.0);
|
|
@@ -468,7 +502,7 @@ fn after_shutdown_checks(
|
|
|
468
502
|
);
|
|
469
503
|
assert_eq!(heartbeat.sdk_name, "temporal-core");
|
|
470
504
|
assert_eq!(heartbeat.sdk_version, "0.1.0");
|
|
471
|
-
assert_eq!(heartbeat.status, WorkerStatus::
|
|
505
|
+
assert_eq!(heartbeat.status, WorkerStatus::ShuttingDown as i32);
|
|
472
506
|
|
|
473
507
|
assert_eq!(start_time.load().unwrap(), heartbeat.start_time.unwrap());
|
|
474
508
|
assert_ne!(
|
|
@@ -524,7 +558,7 @@ fn after_shutdown_checks(
|
|
|
524
558
|
activity_poller_info.last_successful_poll_time.unwrap()
|
|
525
559
|
));
|
|
526
560
|
|
|
527
|
-
assert_eq!(heartbeat.total_sticky_cache_hit,
|
|
561
|
+
assert_eq!(heartbeat.total_sticky_cache_hit, 1);
|
|
528
562
|
assert_eq!(heartbeat.current_sticky_cache_size, 0);
|
|
529
563
|
assert_eq!(
|
|
530
564
|
heartbeat.plugins,
|
|
@@ -541,49 +575,25 @@ fn after_shutdown_checks(
|
|
|
541
575
|
);
|
|
542
576
|
}
|
|
543
577
|
|
|
578
|
+
static HISTORY_WF1_ACTIVITY_STARTED: Notify = Notify::const_new();
|
|
579
|
+
static HISTORY_WF1_ACTIVITY_FINISH: Notify = Notify::const_new();
|
|
580
|
+
static HISTORY_WF2_ACTIVITY_STARTED: Notify = Notify::const_new();
|
|
581
|
+
static HISTORY_WF2_ACTIVITY_FINISH: Notify = Notify::const_new();
|
|
544
582
|
#[tokio::test]
|
|
545
583
|
async fn worker_heartbeat_sticky_cache_miss() {
|
|
546
584
|
let wf_name = "worker_heartbeat_cache_miss";
|
|
547
585
|
let mut starter = new_no_metrics_starter(wf_name);
|
|
548
|
-
starter
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
let client = starter.get_client().await;
|
|
560
|
-
let client_for_orchestrator = client.clone();
|
|
561
|
-
|
|
562
|
-
static HISTORY_WF1_ACTIVITY_STARTED: Notify = Notify::const_new();
|
|
563
|
-
static HISTORY_WF1_ACTIVITY_FINISH: Notify = Notify::const_new();
|
|
564
|
-
static HISTORY_WF2_ACTIVITY_STARTED: Notify = Notify::const_new();
|
|
565
|
-
static HISTORY_WF2_ACTIVITY_FINISH: Notify = Notify::const_new();
|
|
566
|
-
|
|
567
|
-
worker.register_wf(wf_name.to_string(), |ctx: WfContext| async move {
|
|
568
|
-
let wf_marker = ctx
|
|
569
|
-
.get_args()
|
|
570
|
-
.first()
|
|
571
|
-
.and_then(|p| String::from_json_payload(p).ok())
|
|
572
|
-
.unwrap_or_else(|| "wf1".to_string());
|
|
573
|
-
|
|
574
|
-
ctx.activity(ActivityOptions {
|
|
575
|
-
activity_type: "sticky_cache_history_act".to_string(),
|
|
576
|
-
input: wf_marker.clone().as_json_payload().expect("serialize"),
|
|
577
|
-
start_to_close_timeout: Some(Duration::from_secs(5)),
|
|
578
|
-
..Default::default()
|
|
579
|
-
})
|
|
580
|
-
.await;
|
|
581
|
-
|
|
582
|
-
Ok(().into())
|
|
583
|
-
});
|
|
584
|
-
worker.register_activity(
|
|
585
|
-
"sticky_cache_history_act",
|
|
586
|
-
|_ctx: ActContext, marker: String| async move {
|
|
586
|
+
starter.sdk_config.max_cached_workflows = 1_usize;
|
|
587
|
+
starter.sdk_config.tuner = Arc::new(TunerHolder::fixed_size(2, 10, 10, 10));
|
|
588
|
+
|
|
589
|
+
struct StickyCacheActivities;
|
|
590
|
+
#[activities]
|
|
591
|
+
impl StickyCacheActivities {
|
|
592
|
+
#[activity]
|
|
593
|
+
async fn sticky_cache_history_act(
|
|
594
|
+
_ctx: ActivityContext,
|
|
595
|
+
marker: String,
|
|
596
|
+
) -> Result<String, ActivityError> {
|
|
587
597
|
match marker.as_str() {
|
|
588
598
|
"wf1" => {
|
|
589
599
|
HISTORY_WF1_ACTIVITY_STARTED.notify_one();
|
|
@@ -596,31 +606,72 @@ async fn worker_heartbeat_sticky_cache_miss() {
|
|
|
596
606
|
_ => {}
|
|
597
607
|
}
|
|
598
608
|
Ok(marker)
|
|
599
|
-
}
|
|
600
|
-
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
starter
|
|
613
|
+
.sdk_config
|
|
614
|
+
.register_activities(StickyCacheActivities);
|
|
615
|
+
|
|
616
|
+
let mut worker = starter.worker().await;
|
|
617
|
+
worker.fetch_results = false;
|
|
618
|
+
let worker_key = worker.worker_instance_key().to_string();
|
|
619
|
+
let worker_core = worker.core_worker();
|
|
620
|
+
let submitter = worker.get_submitter_handle();
|
|
621
|
+
let wf_opts = starter.workflow_options.clone();
|
|
622
|
+
let client = starter.get_client().await;
|
|
623
|
+
let client_for_orchestrator = client.clone();
|
|
624
|
+
|
|
625
|
+
#[workflow]
|
|
626
|
+
#[derive(Default)]
|
|
627
|
+
struct StickyCacheMissWf;
|
|
628
|
+
|
|
629
|
+
#[workflow_methods]
|
|
630
|
+
impl StickyCacheMissWf {
|
|
631
|
+
#[run]
|
|
632
|
+
#[allow(dead_code)]
|
|
633
|
+
async fn run(ctx: &mut WorkflowContext<Self>, wf_marker: String) -> WorkflowResult<()> {
|
|
634
|
+
let _ = ctx
|
|
635
|
+
.start_activity(
|
|
636
|
+
StickyCacheActivities::sticky_cache_history_act,
|
|
637
|
+
wf_marker.clone(),
|
|
638
|
+
ActivityOptions {
|
|
639
|
+
start_to_close_timeout: Some(Duration::from_secs(5)),
|
|
640
|
+
..Default::default()
|
|
641
|
+
},
|
|
642
|
+
)
|
|
643
|
+
.await;
|
|
644
|
+
|
|
645
|
+
Ok(())
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
worker.register_workflow::<StickyCacheMissWf>();
|
|
601
650
|
|
|
602
651
|
let wf1_id = format!("{wf_name}_wf1");
|
|
603
652
|
let wf2_id = format!("{wf_name}_wf2");
|
|
604
653
|
|
|
605
654
|
let orchestrator = async move {
|
|
655
|
+
let mut opts = wf_opts.clone();
|
|
656
|
+
opts.workflow_id = wf1_id.clone();
|
|
606
657
|
let wf1_run = submitter
|
|
607
658
|
.submit_wf(
|
|
608
|
-
|
|
609
|
-
wf_name.to_string(),
|
|
659
|
+
StickyCacheMissWf::name(),
|
|
610
660
|
vec!["wf1".to_string().as_json_payload().unwrap()],
|
|
611
|
-
|
|
661
|
+
opts,
|
|
612
662
|
)
|
|
613
663
|
.await
|
|
614
664
|
.unwrap();
|
|
615
665
|
|
|
616
666
|
HISTORY_WF1_ACTIVITY_STARTED.notified().await;
|
|
617
667
|
|
|
668
|
+
let mut opts = wf_opts.clone();
|
|
669
|
+
opts.workflow_id = wf2_id.clone();
|
|
618
670
|
let wf2_run = submitter
|
|
619
671
|
.submit_wf(
|
|
620
|
-
|
|
621
|
-
wf_name.to_string(),
|
|
672
|
+
StickyCacheMissWf::name(),
|
|
622
673
|
vec!["wf2".to_string().as_json_payload().unwrap()],
|
|
623
|
-
|
|
674
|
+
opts,
|
|
624
675
|
)
|
|
625
676
|
.await
|
|
626
677
|
.unwrap();
|
|
@@ -628,16 +679,28 @@ async fn worker_heartbeat_sticky_cache_miss() {
|
|
|
628
679
|
HISTORY_WF2_ACTIVITY_STARTED.notified().await;
|
|
629
680
|
|
|
630
681
|
HISTORY_WF1_ACTIVITY_FINISH.notify_one();
|
|
631
|
-
let handle1 =
|
|
682
|
+
let handle1 = WorkflowExecutionInfo {
|
|
683
|
+
namespace: client_for_orchestrator.namespace(),
|
|
684
|
+
workflow_id: wf1_id,
|
|
685
|
+
run_id: Some(wf1_run),
|
|
686
|
+
first_execution_run_id: None,
|
|
687
|
+
}
|
|
688
|
+
.bind_untyped(client_for_orchestrator.clone());
|
|
632
689
|
handle1
|
|
633
|
-
.
|
|
690
|
+
.get_result(Default::default())
|
|
634
691
|
.await
|
|
635
692
|
.expect("wf1 result");
|
|
636
693
|
|
|
637
694
|
HISTORY_WF2_ACTIVITY_FINISH.notify_one();
|
|
638
|
-
let handle2 =
|
|
695
|
+
let handle2 = WorkflowExecutionInfo {
|
|
696
|
+
namespace: client_for_orchestrator.namespace(),
|
|
697
|
+
workflow_id: wf2_id,
|
|
698
|
+
run_id: Some(wf2_run),
|
|
699
|
+
first_execution_run_id: None,
|
|
700
|
+
}
|
|
701
|
+
.bind_untyped(client_for_orchestrator.clone());
|
|
639
702
|
handle2
|
|
640
|
-
.
|
|
703
|
+
.get_result(Default::default())
|
|
641
704
|
.await
|
|
642
705
|
.expect("wf2 result");
|
|
643
706
|
|
|
@@ -665,37 +728,43 @@ async fn worker_heartbeat_sticky_cache_miss() {
|
|
|
665
728
|
async fn worker_heartbeat_multiple_workers() {
|
|
666
729
|
let wf_name = "worker_heartbeat_multi_workers";
|
|
667
730
|
let mut starter = new_no_metrics_starter(wf_name);
|
|
668
|
-
starter
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
.max_cached_workflows(5_usize);
|
|
731
|
+
starter.sdk_config.max_cached_workflows = 5_usize;
|
|
732
|
+
starter.sdk_config.tuner = Arc::new(TunerHolder::fixed_size(5, 10, 10, 10));
|
|
733
|
+
starter.sdk_config.register_activities(StdActivities);
|
|
672
734
|
|
|
673
735
|
let client = starter.get_client().await;
|
|
674
736
|
let starting_hb_len = list_worker_heartbeats(&client, String::new()).await.len();
|
|
675
737
|
|
|
738
|
+
#[workflow]
|
|
739
|
+
#[derive(Default)]
|
|
740
|
+
struct MultiWorkersWf;
|
|
741
|
+
|
|
742
|
+
#[workflow_methods]
|
|
743
|
+
impl MultiWorkersWf {
|
|
744
|
+
#[run]
|
|
745
|
+
#[allow(dead_code)]
|
|
746
|
+
async fn run(_ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
747
|
+
Ok(())
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
|
|
676
751
|
let mut worker_a = starter.worker().await;
|
|
677
|
-
worker_a.
|
|
678
|
-
Ok(().into())
|
|
679
|
-
});
|
|
680
|
-
worker_a.register_activity("failing_act", |_ctx: ActContext, _: String| async move {
|
|
681
|
-
Ok(())
|
|
682
|
-
});
|
|
752
|
+
worker_a.register_workflow::<MultiWorkersWf>();
|
|
683
753
|
|
|
684
754
|
let mut starter_b = starter.clone_no_worker();
|
|
685
755
|
let mut worker_b = starter_b.worker().await;
|
|
686
|
-
worker_b.
|
|
687
|
-
Ok(().into())
|
|
688
|
-
});
|
|
689
|
-
worker_b.register_activity("failing_act", |_ctx: ActContext, _: String| async move {
|
|
690
|
-
Ok(())
|
|
691
|
-
});
|
|
756
|
+
worker_b.register_workflow::<MultiWorkersWf>();
|
|
692
757
|
|
|
693
758
|
let worker_a_key = worker_a.worker_instance_key().to_string();
|
|
694
759
|
let worker_b_key = worker_b.worker_instance_key().to_string();
|
|
695
|
-
let _ = starter
|
|
760
|
+
let _ = starter
|
|
761
|
+
.start_with_worker(MultiWorkersWf::name(), &mut worker_a)
|
|
762
|
+
.await;
|
|
696
763
|
worker_a.run_until_done().await.unwrap();
|
|
697
764
|
|
|
698
|
-
let _ = starter_b
|
|
765
|
+
let _ = starter_b
|
|
766
|
+
.start_with_worker(MultiWorkersWf::name(), &mut worker_b)
|
|
767
|
+
.await;
|
|
699
768
|
worker_b.run_until_done().await.unwrap();
|
|
700
769
|
|
|
701
770
|
sleep(Duration::from_secs(2)).await;
|
|
@@ -708,12 +777,16 @@ async fn worker_heartbeat_multiple_workers() {
|
|
|
708
777
|
assert!(keys.contains(&worker_a_key));
|
|
709
778
|
assert!(keys.contains(&worker_b_key));
|
|
710
779
|
|
|
711
|
-
// Verify both heartbeats contain the same shared
|
|
712
|
-
let
|
|
780
|
+
// Verify both heartbeats contain the same shared worker_grouping_key
|
|
781
|
+
let worker_grouping_keys: HashSet<_> = all
|
|
713
782
|
.iter()
|
|
714
|
-
.filter_map(|hb|
|
|
783
|
+
.filter_map(|hb| {
|
|
784
|
+
hb.host_info
|
|
785
|
+
.as_ref()
|
|
786
|
+
.map(|info| info.worker_grouping_key.clone())
|
|
787
|
+
})
|
|
715
788
|
.collect();
|
|
716
|
-
assert!(
|
|
789
|
+
assert!(worker_grouping_keys.len() > starting_hb_len);
|
|
717
790
|
|
|
718
791
|
let filtered =
|
|
719
792
|
list_worker_heartbeats(&client, format!("WorkerInstanceKey=\"{worker_a_key}\"")).await;
|
|
@@ -721,7 +794,7 @@ async fn worker_heartbeat_multiple_workers() {
|
|
|
721
794
|
assert_eq!(filtered[0].worker_instance_key, worker_a_key);
|
|
722
795
|
|
|
723
796
|
// Verify describe worker gives the same heartbeat as listworker
|
|
724
|
-
let mut raw_client = client.
|
|
797
|
+
let mut raw_client = client.clone();
|
|
725
798
|
let describe_worker_a = WorkflowService::describe_worker(
|
|
726
799
|
&mut raw_client,
|
|
727
800
|
DescribeWorkerRequest {
|
|
@@ -761,72 +834,103 @@ async fn worker_heartbeat_multiple_workers() {
|
|
|
761
834
|
assert_eq!(describe_worker_b, filtered_b[0]);
|
|
762
835
|
}
|
|
763
836
|
|
|
837
|
+
static ACT_COUNT: AtomicU64 = AtomicU64::new(0);
|
|
838
|
+
static WF_COUNT: AtomicU64 = AtomicU64::new(0);
|
|
839
|
+
static ACT_FAIL: Notify = Notify::const_new();
|
|
840
|
+
static WF_FAIL: Notify = Notify::const_new();
|
|
764
841
|
#[tokio::test]
|
|
765
842
|
async fn worker_heartbeat_failure_metrics() {
|
|
766
|
-
const WORKFLOW_CONTINUE_SIGNAL: &str = "workflow-continue";
|
|
767
|
-
|
|
768
843
|
let wf_name = "worker_heartbeat_failure_metrics";
|
|
769
844
|
let mut starter = new_no_metrics_starter(wf_name);
|
|
770
|
-
starter.
|
|
845
|
+
starter.sdk_config.tuner = Arc::new(TunerHolder::fixed_size(10, 5, 10, 10));
|
|
846
|
+
|
|
847
|
+
struct FailingActivities;
|
|
848
|
+
#[activities]
|
|
849
|
+
impl FailingActivities {
|
|
850
|
+
#[activity]
|
|
851
|
+
async fn failing_act(_ctx: ActivityContext, _: String) -> Result<(), ActivityError> {
|
|
852
|
+
if ACT_COUNT.load(Ordering::Relaxed) == 3 {
|
|
853
|
+
return Ok(());
|
|
854
|
+
}
|
|
855
|
+
ACT_COUNT.fetch_add(1, Ordering::Relaxed);
|
|
856
|
+
ACT_FAIL.notify_one();
|
|
857
|
+
Err(anyhow!("Expected error").into())
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
starter.sdk_config.register_activities(FailingActivities);
|
|
771
862
|
|
|
772
863
|
let mut worker = starter.worker().await;
|
|
773
864
|
let worker_instance_key = worker.worker_instance_key();
|
|
774
|
-
static ACT_COUNT: AtomicU64 = AtomicU64::new(0);
|
|
775
|
-
static WF_COUNT: AtomicU64 = AtomicU64::new(0);
|
|
776
|
-
static ACT_FAIL: Notify = Notify::const_new();
|
|
777
|
-
static WF_FAIL: Notify = Notify::const_new();
|
|
778
|
-
worker.register_wf(wf_name.to_string(), |ctx: WfContext| async move {
|
|
779
|
-
let _ = ctx
|
|
780
|
-
.activity(ActivityOptions {
|
|
781
|
-
activity_type: "failing_act".to_string(),
|
|
782
|
-
input: "boom".as_json_payload().expect("serialize"),
|
|
783
|
-
start_to_close_timeout: Some(Duration::from_secs(5)),
|
|
784
|
-
retry_policy: Some(RetryPolicy {
|
|
785
|
-
initial_interval: Some(prost_dur!(from_millis(10))),
|
|
786
|
-
backoff_coefficient: 1.0,
|
|
787
|
-
maximum_attempts: 4,
|
|
788
|
-
..Default::default()
|
|
789
|
-
}),
|
|
790
|
-
..Default::default()
|
|
791
|
-
})
|
|
792
|
-
.await;
|
|
793
865
|
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
866
|
+
#[workflow]
|
|
867
|
+
#[derive(Default)]
|
|
868
|
+
struct FailureMetricsWf {
|
|
869
|
+
signal_received: bool,
|
|
870
|
+
}
|
|
799
871
|
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
872
|
+
#[workflow_methods]
|
|
873
|
+
impl FailureMetricsWf {
|
|
874
|
+
#[run]
|
|
875
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
876
|
+
let _ = ctx
|
|
877
|
+
.start_activity(
|
|
878
|
+
FailingActivities::failing_act,
|
|
879
|
+
"boom".to_string(),
|
|
880
|
+
ActivityOptions {
|
|
881
|
+
start_to_close_timeout: Some(Duration::from_secs(5)),
|
|
882
|
+
retry_policy: Some(RetryPolicy {
|
|
883
|
+
initial_interval: Some(prost_dur!(from_millis(10))),
|
|
884
|
+
backoff_coefficient: 1.0,
|
|
885
|
+
maximum_attempts: 4,
|
|
886
|
+
..Default::default()
|
|
887
|
+
}),
|
|
888
|
+
..Default::default()
|
|
889
|
+
},
|
|
890
|
+
)
|
|
891
|
+
.await;
|
|
892
|
+
|
|
893
|
+
if WF_COUNT.load(Ordering::Relaxed) == 0 {
|
|
894
|
+
WF_COUNT.fetch_add(1, Ordering::Relaxed);
|
|
895
|
+
WF_FAIL.notify_one();
|
|
896
|
+
panic!("expected WF panic");
|
|
897
|
+
}
|
|
806
898
|
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
return Ok(());
|
|
899
|
+
ctx.wait_condition(|s| s.signal_received).await;
|
|
900
|
+
Ok(())
|
|
810
901
|
}
|
|
811
|
-
ACT_COUNT.fetch_add(1, Ordering::Relaxed);
|
|
812
|
-
ACT_FAIL.notify_one();
|
|
813
|
-
Err(anyhow!("Expected error").into())
|
|
814
|
-
});
|
|
815
902
|
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
}
|
|
903
|
+
#[signal]
|
|
904
|
+
fn handle_continue_signal(&mut self, _ctx: &mut SyncWorkflowContext<Self>, _: ()) {
|
|
905
|
+
self.signal_received = true;
|
|
906
|
+
}
|
|
907
|
+
}
|
|
821
908
|
|
|
822
|
-
|
|
909
|
+
worker.register_workflow::<FailureMetricsWf>();
|
|
910
|
+
|
|
911
|
+
let worker_key = worker_instance_key.to_string();
|
|
912
|
+
let task_queue = starter.get_task_queue().to_owned();
|
|
913
|
+
let workflow_id = starter.get_wf_id();
|
|
914
|
+
let handle = worker
|
|
915
|
+
.submit_workflow(
|
|
916
|
+
FailureMetricsWf::run,
|
|
917
|
+
(),
|
|
918
|
+
WorkflowStartOptions::new(task_queue, workflow_id)
|
|
919
|
+
.retry_policy(RetryPolicy {
|
|
920
|
+
maximum_attempts: 2,
|
|
921
|
+
..Default::default()
|
|
922
|
+
})
|
|
923
|
+
.build(),
|
|
924
|
+
)
|
|
925
|
+
.await
|
|
926
|
+
.unwrap();
|
|
823
927
|
|
|
824
928
|
let test_fut = async {
|
|
825
929
|
ACT_FAIL.notified().await;
|
|
826
930
|
let client = starter.get_client().await;
|
|
827
931
|
eventually(
|
|
828
932
|
|| async {
|
|
829
|
-
let mut raw_client =
|
|
933
|
+
let mut raw_client = client.clone();
|
|
830
934
|
|
|
831
935
|
let workers_list = WorkflowService::list_workers(
|
|
832
936
|
&mut raw_client,
|
|
@@ -872,7 +976,7 @@ async fn worker_heartbeat_failure_metrics() {
|
|
|
872
976
|
|
|
873
977
|
eventually(
|
|
874
978
|
|| async {
|
|
875
|
-
let mut raw_client =
|
|
979
|
+
let mut raw_client = client.clone();
|
|
876
980
|
let workers_list = WorkflowService::list_workers(
|
|
877
981
|
&mut raw_client,
|
|
878
982
|
ListWorkersRequest {
|
|
@@ -909,13 +1013,11 @@ async fn worker_heartbeat_failure_metrics() {
|
|
|
909
1013
|
)
|
|
910
1014
|
.await
|
|
911
1015
|
.unwrap();
|
|
912
|
-
|
|
913
|
-
.
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
None,
|
|
918
|
-
None,
|
|
1016
|
+
handle
|
|
1017
|
+
.signal(
|
|
1018
|
+
FailureMetricsWf::handle_continue_signal,
|
|
1019
|
+
(),
|
|
1020
|
+
WorkflowSignalOptions::default(),
|
|
919
1021
|
)
|
|
920
1022
|
.await
|
|
921
1023
|
.unwrap();
|
|
@@ -942,38 +1044,49 @@ async fn worker_heartbeat_failure_metrics() {
|
|
|
942
1044
|
#[tokio::test]
|
|
943
1045
|
async fn worker_heartbeat_no_runtime_heartbeat() {
|
|
944
1046
|
let wf_name = "worker_heartbeat_no_runtime_heartbeat";
|
|
945
|
-
let runtimeopts =
|
|
1047
|
+
let runtimeopts = RuntimeOptions::builder()
|
|
946
1048
|
.telemetry_options(get_integ_telem_options())
|
|
947
|
-
.heartbeat_interval(None)
|
|
1049
|
+
.heartbeat_interval(None)
|
|
948
1050
|
.build()
|
|
949
1051
|
.unwrap();
|
|
950
1052
|
let rt = CoreRuntime::new_assume_tokio(runtimeopts).unwrap();
|
|
951
1053
|
let mut starter = CoreWfStarter::new_with_runtime(wf_name, rt);
|
|
1054
|
+
starter.sdk_config.register_activities(StdActivities);
|
|
952
1055
|
let mut worker = starter.worker().await;
|
|
953
1056
|
let worker_instance_key = worker.worker_instance_key();
|
|
954
1057
|
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
1058
|
+
#[workflow]
|
|
1059
|
+
#[derive(Default)]
|
|
1060
|
+
struct NoRuntimeHeartbeatWf;
|
|
1061
|
+
|
|
1062
|
+
#[workflow_methods]
|
|
1063
|
+
impl NoRuntimeHeartbeatWf {
|
|
1064
|
+
#[run]
|
|
1065
|
+
#[allow(dead_code)]
|
|
1066
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
1067
|
+
let _ = ctx
|
|
1068
|
+
.start_activity(
|
|
1069
|
+
StdActivities::echo,
|
|
1070
|
+
"pass".to_string(),
|
|
1071
|
+
ActivityOptions {
|
|
1072
|
+
start_to_close_timeout: Some(Duration::from_secs(1)),
|
|
1073
|
+
..Default::default()
|
|
1074
|
+
},
|
|
1075
|
+
)
|
|
1076
|
+
.await;
|
|
1077
|
+
Ok(())
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
965
1080
|
|
|
966
|
-
worker.
|
|
967
|
-
Ok(i)
|
|
968
|
-
});
|
|
1081
|
+
worker.register_workflow::<NoRuntimeHeartbeatWf>();
|
|
969
1082
|
|
|
970
1083
|
starter
|
|
971
|
-
.start_with_worker(
|
|
1084
|
+
.start_with_worker(NoRuntimeHeartbeatWf::name(), &mut worker)
|
|
972
1085
|
.await;
|
|
973
1086
|
|
|
974
1087
|
worker.run_until_done().await.unwrap();
|
|
975
1088
|
let client = starter.get_client().await;
|
|
976
|
-
let mut raw_client =
|
|
1089
|
+
let mut raw_client = client.clone();
|
|
977
1090
|
let workers_list = WorkflowService::list_workers(
|
|
978
1091
|
&mut raw_client,
|
|
979
1092
|
ListWorkersRequest {
|
|
@@ -1002,39 +1115,50 @@ async fn worker_heartbeat_no_runtime_heartbeat() {
|
|
|
1002
1115
|
#[tokio::test]
|
|
1003
1116
|
async fn worker_heartbeat_skip_client_worker_set_check() {
|
|
1004
1117
|
let wf_name = "worker_heartbeat_skip_client_worker_set_check";
|
|
1005
|
-
let runtimeopts =
|
|
1118
|
+
let runtimeopts = RuntimeOptions::builder()
|
|
1006
1119
|
.telemetry_options(get_integ_telem_options())
|
|
1007
1120
|
.heartbeat_interval(Some(Duration::from_secs(1)))
|
|
1008
1121
|
.build()
|
|
1009
1122
|
.unwrap();
|
|
1010
1123
|
let rt = CoreRuntime::new_assume_tokio(runtimeopts).unwrap();
|
|
1011
1124
|
let mut starter = CoreWfStarter::new_with_runtime(wf_name, rt);
|
|
1012
|
-
starter.
|
|
1125
|
+
starter.set_core_cfg_mutator(|m| m.skip_client_worker_set_check = true);
|
|
1126
|
+
starter.sdk_config.register_activities(StdActivities);
|
|
1013
1127
|
let mut worker = starter.worker().await;
|
|
1014
1128
|
let worker_instance_key = worker.worker_instance_key();
|
|
1015
1129
|
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1130
|
+
#[workflow]
|
|
1131
|
+
#[derive(Default)]
|
|
1132
|
+
struct SkipClientWorkerSetCheckWf;
|
|
1133
|
+
|
|
1134
|
+
#[workflow_methods]
|
|
1135
|
+
impl SkipClientWorkerSetCheckWf {
|
|
1136
|
+
#[run]
|
|
1137
|
+
#[allow(dead_code)]
|
|
1138
|
+
async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
|
|
1139
|
+
let _ = ctx
|
|
1140
|
+
.start_activity(
|
|
1141
|
+
StdActivities::echo,
|
|
1142
|
+
"pass".to_string(),
|
|
1143
|
+
ActivityOptions {
|
|
1144
|
+
start_to_close_timeout: Some(Duration::from_secs(1)),
|
|
1145
|
+
..Default::default()
|
|
1146
|
+
},
|
|
1147
|
+
)
|
|
1148
|
+
.await;
|
|
1149
|
+
Ok(())
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1026
1152
|
|
|
1027
|
-
worker.
|
|
1028
|
-
Ok(i)
|
|
1029
|
-
});
|
|
1153
|
+
worker.register_workflow::<SkipClientWorkerSetCheckWf>();
|
|
1030
1154
|
|
|
1031
1155
|
starter
|
|
1032
|
-
.start_with_worker(
|
|
1156
|
+
.start_with_worker(SkipClientWorkerSetCheckWf::name(), &mut worker)
|
|
1033
1157
|
.await;
|
|
1034
1158
|
|
|
1035
1159
|
worker.run_until_done().await.unwrap();
|
|
1036
1160
|
let client = starter.get_client().await;
|
|
1037
|
-
let mut raw_client =
|
|
1161
|
+
let mut raw_client = client.clone();
|
|
1038
1162
|
let workers_list = WorkflowService::list_workers(
|
|
1039
1163
|
&mut raw_client,
|
|
1040
1164
|
ListWorkersRequest {
|