@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,17 +1,15 @@
|
|
|
1
1
|
use crate::{
|
|
2
2
|
abstractions::UsedMeteredSemPermit,
|
|
3
3
|
pollers::{BoxedNexusPoller, NexusPollItem, new_nexus_task_poller},
|
|
4
|
-
telemetry::{
|
|
5
|
-
|
|
6
|
-
metrics::{FailureReason, MetricsContext},
|
|
7
|
-
},
|
|
8
|
-
worker::client::WorkerClient,
|
|
4
|
+
telemetry::metrics::{self, FailureReason, MetricsContext},
|
|
5
|
+
worker::{CompleteNexusError, NexusSlotKind, PollError, client::WorkerClient},
|
|
9
6
|
};
|
|
10
7
|
use anyhow::anyhow;
|
|
11
8
|
use futures_util::{
|
|
12
9
|
Stream, StreamExt, stream,
|
|
13
10
|
stream::{BoxStream, PollNext},
|
|
14
11
|
};
|
|
12
|
+
use prost_types::Timestamp;
|
|
15
13
|
use std::{
|
|
16
14
|
collections::HashMap,
|
|
17
15
|
sync::{
|
|
@@ -20,24 +18,26 @@ use std::{
|
|
|
20
18
|
},
|
|
21
19
|
time::{Duration, Instant, SystemTime},
|
|
22
20
|
};
|
|
23
|
-
use temporalio_common::{
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
CancelNexusTask, NexusTask, NexusTaskCancelReason, nexus_task,
|
|
31
|
-
nexus_task_completion,
|
|
32
|
-
},
|
|
21
|
+
use temporalio_common::protos::{
|
|
22
|
+
TaskToken,
|
|
23
|
+
coresdk::{
|
|
24
|
+
NexusSlotInfo,
|
|
25
|
+
nexus::{
|
|
26
|
+
CancelNexusTask, NexusOperationErrorState, NexusTask, NexusTaskCancelReason,
|
|
27
|
+
nexus_task, nexus_task_completion,
|
|
33
28
|
},
|
|
34
|
-
|
|
29
|
+
},
|
|
30
|
+
temporal::api::{
|
|
31
|
+
failure::v1::failure::FailureInfo,
|
|
32
|
+
nexus::{
|
|
35
33
|
self,
|
|
36
|
-
v1::{
|
|
34
|
+
v1::{
|
|
35
|
+
NexusTaskFailure, UnsuccessfulOperationError, request::Variant, response,
|
|
36
|
+
start_operation_response,
|
|
37
|
+
},
|
|
37
38
|
},
|
|
38
|
-
utilities::normalize_http_headers,
|
|
39
39
|
},
|
|
40
|
-
|
|
40
|
+
utilities::normalize_http_headers,
|
|
41
41
|
};
|
|
42
42
|
use tokio::{
|
|
43
43
|
join,
|
|
@@ -124,20 +124,78 @@ impl NexusManager {
|
|
|
124
124
|
.nexus_task_execution_latency(task_info.start_time.elapsed());
|
|
125
125
|
task_info.timeout_task.inspect(|jh| jh.abort());
|
|
126
126
|
let (did_send, maybe_net_err) = match status {
|
|
127
|
-
nexus_task_completion::Status::Completed(c) => {
|
|
127
|
+
nexus_task_completion::Status::Completed(mut c) => {
|
|
128
128
|
// Server doesn't provide obvious errors for this validation, so it's done
|
|
129
129
|
// here to make life easier for lang implementors.
|
|
130
|
-
match &c.variant {
|
|
130
|
+
match &mut c.variant {
|
|
131
131
|
Some(response::Variant::StartOperation(so)) => {
|
|
132
|
+
#[allow(deprecated)]
|
|
132
133
|
if let Some(start_operation_response::Variant::OperationError(oe)) =
|
|
133
134
|
so.variant.as_ref()
|
|
134
135
|
{
|
|
136
|
+
// Deprecated branch left for SDKs that have not yet started using Temporal failures
|
|
135
137
|
self.metrics
|
|
136
138
|
.with_new_attrs([metrics::failure_reason(
|
|
137
139
|
FailureReason::NexusOperation(oe.operation_state.clone()),
|
|
138
140
|
)])
|
|
139
141
|
.nexus_task_execution_failed();
|
|
140
|
-
}
|
|
142
|
+
} else if let Some(start_operation_response::Variant::Failure(f)) =
|
|
143
|
+
&mut so.variant
|
|
144
|
+
{
|
|
145
|
+
let operation_state = match &f.failure_info {
|
|
146
|
+
Some(FailureInfo::ApplicationFailureInfo(_)) => {
|
|
147
|
+
NexusOperationErrorState::Failed
|
|
148
|
+
}
|
|
149
|
+
Some(FailureInfo::CanceledFailureInfo(_)) => {
|
|
150
|
+
NexusOperationErrorState::Canceled
|
|
151
|
+
}
|
|
152
|
+
_ => {
|
|
153
|
+
return Err(CompleteNexusError::MalformedNexusCompletion {
|
|
154
|
+
reason: "Nexus StartOperationResponse with a failure must contain ApplicationFailureInfo or CanceledFailureInfo"
|
|
155
|
+
.to_string(),
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
let use_temporal_failures = task_info
|
|
161
|
+
.capabilities
|
|
162
|
+
.as_ref()
|
|
163
|
+
.map(|c| c.temporal_failure_responses)
|
|
164
|
+
.unwrap_or_default();
|
|
165
|
+
|
|
166
|
+
if !use_temporal_failures {
|
|
167
|
+
// Take the failure from the StartOperationResponse variant
|
|
168
|
+
let failure = std::mem::take(f);
|
|
169
|
+
|
|
170
|
+
// Convert the failure to an UnsuccessfulOperationError
|
|
171
|
+
let failure =
|
|
172
|
+
nexus::v1::Failure::try_from(failure)
|
|
173
|
+
.map_err(|err| CompleteNexusError::MalformedNexusCompletion {
|
|
174
|
+
reason: format!(
|
|
175
|
+
"error converting temporal failure to nexus failure: {:?}",
|
|
176
|
+
err
|
|
177
|
+
),
|
|
178
|
+
})?;
|
|
179
|
+
|
|
180
|
+
// Set StartOperationResponse variant to new UnsuccessfulOperationError
|
|
181
|
+
so.variant = Some(
|
|
182
|
+
#[allow(deprecated)]
|
|
183
|
+
start_operation_response::Variant::OperationError(
|
|
184
|
+
UnsuccessfulOperationError {
|
|
185
|
+
operation_state: operation_state.to_string(),
|
|
186
|
+
failure: Some(failure),
|
|
187
|
+
},
|
|
188
|
+
),
|
|
189
|
+
)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
self.metrics
|
|
193
|
+
.with_new_attrs([metrics::failure_reason(
|
|
194
|
+
FailureReason::NexusOperation(operation_state.to_string()),
|
|
195
|
+
)])
|
|
196
|
+
.nexus_task_execution_failed();
|
|
197
|
+
}
|
|
198
|
+
|
|
141
199
|
if task_info.request_kind != RequestKind::Start {
|
|
142
200
|
return Err(CompleteNexusError::MalformedNexusCompletion {
|
|
143
201
|
reason: "Nexus response was StartOperation but request was not"
|
|
@@ -163,19 +221,76 @@ impl NexusManager {
|
|
|
163
221
|
}
|
|
164
222
|
(true, client.complete_nexus_task(tt, c).await.err())
|
|
165
223
|
}
|
|
224
|
+
|
|
166
225
|
nexus_task_completion::Status::AckCancel(_) => {
|
|
167
226
|
self.metrics
|
|
168
227
|
.with_new_attrs([metrics::failure_reason(FailureReason::Timeout)])
|
|
169
228
|
.nexus_task_execution_failed();
|
|
170
229
|
(false, None)
|
|
171
230
|
}
|
|
231
|
+
|
|
232
|
+
#[allow(deprecated)]
|
|
172
233
|
nexus_task_completion::Status::Error(e) => {
|
|
234
|
+
// Deprecated branch left for SDKs that have not yet started using Temporal failures
|
|
173
235
|
self.metrics
|
|
174
236
|
.with_new_attrs([metrics::failure_reason(
|
|
175
237
|
FailureReason::NexusHandlerError(e.error_type.clone()),
|
|
176
238
|
)])
|
|
177
239
|
.nexus_task_execution_failed();
|
|
178
|
-
|
|
240
|
+
let maybe_net_err = client
|
|
241
|
+
.fail_nexus_task(tt, NexusTaskFailure::Legacy(e))
|
|
242
|
+
.await
|
|
243
|
+
.err();
|
|
244
|
+
(true, maybe_net_err)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
nexus_task_completion::Status::Failure(f) => {
|
|
248
|
+
let use_temporal_failures = task_info
|
|
249
|
+
.capabilities
|
|
250
|
+
.as_ref()
|
|
251
|
+
.map(|c| c.temporal_failure_responses)
|
|
252
|
+
.unwrap_or_default();
|
|
253
|
+
|
|
254
|
+
let failure_info = match &f.failure_info {
|
|
255
|
+
Some(FailureInfo::NexusHandlerFailureInfo(failure_info)) => {
|
|
256
|
+
failure_info.clone()
|
|
257
|
+
}
|
|
258
|
+
_ => {
|
|
259
|
+
return Err(CompleteNexusError::MalformedNexusCompletion {
|
|
260
|
+
reason: "Nexus completions with a failure must contain a NexusHandlerFailureInfo".to_string(),
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
self.metrics
|
|
266
|
+
.with_new_attrs([metrics::failure_reason(
|
|
267
|
+
FailureReason::NexusHandlerError(failure_info.r#type.clone()),
|
|
268
|
+
)])
|
|
269
|
+
.nexus_task_execution_failed();
|
|
270
|
+
|
|
271
|
+
let task_failure = if use_temporal_failures {
|
|
272
|
+
NexusTaskFailure::Temporal(f)
|
|
273
|
+
} else {
|
|
274
|
+
let failure = nexus::v1::Failure::try_from(f).map_err(|err| {
|
|
275
|
+
CompleteNexusError::MalformedNexusCompletion {
|
|
276
|
+
reason: format!(
|
|
277
|
+
"error converting temporal failure to nexus failure: {:?}",
|
|
278
|
+
err
|
|
279
|
+
),
|
|
280
|
+
}
|
|
281
|
+
})?;
|
|
282
|
+
|
|
283
|
+
let h = nexus::v1::HandlerError {
|
|
284
|
+
error_type: failure_info.r#type,
|
|
285
|
+
failure: Some(failure),
|
|
286
|
+
//NexusHandlerFailureInfo and HandlerError both use enums::v1::NexusHandlerErrorRetryBehavior
|
|
287
|
+
retry_behavior: failure_info.retry_behavior,
|
|
288
|
+
};
|
|
289
|
+
NexusTaskFailure::Legacy(h)
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
let maybe_net_err = client.fail_nexus_task(tt, task_failure).await.err();
|
|
293
|
+
(true, maybe_net_err)
|
|
179
294
|
}
|
|
180
295
|
};
|
|
181
296
|
|
|
@@ -264,6 +379,7 @@ where
|
|
|
264
379
|
|
|
265
380
|
let tt = TaskToken(t.resp.task_token.clone());
|
|
266
381
|
let mut timeout_task = None;
|
|
382
|
+
let mut request_deadline: Option<Timestamp> = None;
|
|
267
383
|
if let Some(timeout_str) = t
|
|
268
384
|
.resp
|
|
269
385
|
.request
|
|
@@ -271,6 +387,7 @@ where
|
|
|
271
387
|
.and_then(|r| r.header.get(REQUEST_TIMEOUT_HEADER))
|
|
272
388
|
{
|
|
273
389
|
if let Ok(timeout_dur) = parse_request_timeout(timeout_str) {
|
|
390
|
+
request_deadline = Some((SystemTime::now() + timeout_dur).into());
|
|
274
391
|
let tt_clone = tt.clone();
|
|
275
392
|
let cancels_tx = self.cancels_tx.clone();
|
|
276
393
|
timeout_task = Some(tokio::task::spawn(async move {
|
|
@@ -314,6 +431,12 @@ where
|
|
|
314
431
|
),
|
|
315
432
|
})
|
|
316
433
|
.unwrap_or_default();
|
|
434
|
+
|
|
435
|
+
let capabilities = t
|
|
436
|
+
.resp
|
|
437
|
+
.request
|
|
438
|
+
.as_ref()
|
|
439
|
+
.and_then(|r| r.capabilities);
|
|
317
440
|
self.outstanding_task_map.lock().insert(
|
|
318
441
|
tt,
|
|
319
442
|
NexusInFlightTask {
|
|
@@ -327,16 +450,19 @@ where
|
|
|
327
450
|
.and_then(|t| t.try_into().ok()),
|
|
328
451
|
start_time: Instant::now(),
|
|
329
452
|
_permit: t.permit.into_used(NexusSlotInfo { service, operation }),
|
|
453
|
+
capabilities,
|
|
330
454
|
},
|
|
331
455
|
);
|
|
332
456
|
Some(Ok(NexusTask {
|
|
333
457
|
variant: Some(nexus_task::Variant::Task(t.resp)),
|
|
458
|
+
request_deadline,
|
|
334
459
|
}))
|
|
335
460
|
},
|
|
336
461
|
Err(e) => Some(Err(PollError::TonicError(e)))
|
|
337
462
|
},
|
|
338
463
|
TaskStreamInput::Cancel(c) => Some(Ok(NexusTask {
|
|
339
464
|
variant: Some(nexus_task::Variant::CancelTask(c)),
|
|
465
|
+
request_deadline: None,
|
|
340
466
|
})),
|
|
341
467
|
TaskStreamInput::SourceComplete => {
|
|
342
468
|
source_done.cancel();
|
|
@@ -382,6 +508,7 @@ struct NexusInFlightTask {
|
|
|
382
508
|
scheduled_time: Option<SystemTime>,
|
|
383
509
|
start_time: Instant,
|
|
384
510
|
_permit: UsedMeteredSemPermit<NexusSlotKind>,
|
|
511
|
+
capabilities: Option<nexus::v1::request::Capabilities>,
|
|
385
512
|
}
|
|
386
513
|
|
|
387
514
|
#[derive(Eq, PartialEq, Copy, Clone, Default)]
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
use crate::{
|
|
6
6
|
abstractions::{MeteredPermitDealer, OwnedMeteredSemPermit},
|
|
7
7
|
protosext::ValidPollWFTQResponse,
|
|
8
|
-
worker::workflow::wft_poller::validate_wft,
|
|
8
|
+
worker::{WorkflowSlotKind, workflow::wft_poller::validate_wft},
|
|
9
9
|
};
|
|
10
10
|
use temporalio_client::worker::Slot as SlotTrait;
|
|
11
11
|
use temporalio_common::{
|
|
12
12
|
protos::temporal::api::workflowservice::v1::PollWorkflowTaskQueueResponse,
|
|
13
|
-
worker::
|
|
13
|
+
worker::WorkerDeploymentOptions,
|
|
14
14
|
};
|
|
15
15
|
use tokio::sync::mpsc::UnboundedSender;
|
|
16
16
|
use tonic::Status;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
use
|
|
2
|
-
use temporalio_common::worker::{
|
|
1
|
+
use crate::worker::{
|
|
3
2
|
SlotKind, SlotMarkUsedContext, SlotReleaseContext, SlotReservationContext, SlotSupplier,
|
|
4
3
|
SlotSupplierPermit,
|
|
5
4
|
};
|
|
5
|
+
use std::{marker::PhantomData, sync::Arc};
|
|
6
6
|
use tokio::sync::Semaphore;
|
|
7
7
|
|
|
8
8
|
/// Implements [SlotSupplier] with a fixed number of slots
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
use crate::worker::{
|
|
2
|
+
ActivitySlotKind, LocalActivitySlotKind, NexusSlotKind, SlotInfo, SlotInfoTrait, SlotKind,
|
|
3
|
+
SlotKindType, SlotMarkUsedContext, SlotReleaseContext, SlotReservationContext, SlotSupplier,
|
|
4
|
+
SlotSupplierPermit, WorkerTuner, WorkflowSlotKind,
|
|
5
|
+
};
|
|
1
6
|
use crossbeam_utils::atomic::AtomicCell;
|
|
2
7
|
use parking_lot::Mutex;
|
|
3
8
|
use std::{
|
|
@@ -12,18 +17,11 @@ use std::{
|
|
|
12
17
|
thread,
|
|
13
18
|
time::{Duration, Instant},
|
|
14
19
|
};
|
|
15
|
-
use temporalio_common::{
|
|
16
|
-
telemetry::metrics::{CoreMeter, GaugeF64, MetricAttributes, TemporalMeter},
|
|
17
|
-
worker::{
|
|
18
|
-
ActivitySlotKind, LocalActivitySlotKind, NexusSlotKind, SlotInfo, SlotInfoTrait, SlotKind,
|
|
19
|
-
SlotKindType, SlotMarkUsedContext, SlotReleaseContext, SlotReservationContext,
|
|
20
|
-
SlotSupplier, SlotSupplierPermit, WorkerTuner, WorkflowSlotKind,
|
|
21
|
-
},
|
|
22
|
-
};
|
|
20
|
+
use temporalio_common::telemetry::metrics::{GaugeF64, MetricAttributes, TemporalMeter};
|
|
23
21
|
use tokio::{sync::watch, task::JoinHandle};
|
|
24
22
|
|
|
25
|
-
/// Implements [WorkerTuner] and attempts to maintain certain levels of resource
|
|
26
|
-
/// under load.
|
|
23
|
+
/// Implements [crate::worker::WorkerTuner] and attempts to maintain certain levels of resource
|
|
24
|
+
/// usage when under load.
|
|
27
25
|
///
|
|
28
26
|
/// It does so by using two PID controllers, one for memory and one for CPU, which are fed the
|
|
29
27
|
/// current usage levels of their respective resource as measurements. The user specifies a target
|
|
@@ -43,11 +41,10 @@ impl ResourceBasedTuner<RealSysInfo> {
|
|
|
43
41
|
/// Create an instance attempting to target the provided memory and cpu thresholds as values
|
|
44
42
|
/// between 0 and 1.
|
|
45
43
|
pub fn new(target_mem_usage: f64, target_cpu_usage: f64) -> Self {
|
|
46
|
-
let opts =
|
|
44
|
+
let opts = ResourceBasedSlotsOptions::builder()
|
|
47
45
|
.target_mem_usage(target_mem_usage)
|
|
48
46
|
.target_cpu_usage(target_cpu_usage)
|
|
49
|
-
.build()
|
|
50
|
-
.expect("default resource based slot options can't fail to build");
|
|
47
|
+
.build();
|
|
51
48
|
let controller = ResourceController::new_with_sysinfo(opts, Arc::new(RealSysInfo::new()));
|
|
52
49
|
Self::new_from_controller(controller)
|
|
53
50
|
}
|
|
@@ -163,7 +160,7 @@ pub(crate) struct ResourceBasedSlotsForType<MI, SK> {
|
|
|
163
160
|
_slot_kind: PhantomData<SK>,
|
|
164
161
|
}
|
|
165
162
|
/// Allows for the full customization of the PID options for a resource based tuner
|
|
166
|
-
#[derive(Clone, Debug,
|
|
163
|
+
#[derive(Clone, Debug, bon::Builder)]
|
|
167
164
|
#[non_exhaustive]
|
|
168
165
|
pub struct ResourceBasedSlotsOptions {
|
|
169
166
|
/// A value in the range [0.0, 1.0] representing the target memory usage.
|
|
@@ -172,30 +169,30 @@ pub struct ResourceBasedSlotsOptions {
|
|
|
172
169
|
pub target_cpu_usage: f64,
|
|
173
170
|
|
|
174
171
|
/// See [pid::Pid::p]
|
|
175
|
-
#[builder(default =
|
|
172
|
+
#[builder(default = 5.0)]
|
|
176
173
|
pub mem_p_gain: f64,
|
|
177
174
|
/// See [pid::Pid::i]
|
|
178
|
-
#[builder(default =
|
|
175
|
+
#[builder(default = 0.0)]
|
|
179
176
|
pub mem_i_gain: f64,
|
|
180
177
|
/// See [pid::Pid::d]
|
|
181
|
-
#[builder(default =
|
|
178
|
+
#[builder(default = 1.0)]
|
|
182
179
|
pub mem_d_gain: f64,
|
|
183
180
|
/// If the mem PID controller outputs a value higher than this, we say the mem half of things
|
|
184
181
|
/// will allow a slot
|
|
185
|
-
#[builder(default =
|
|
182
|
+
#[builder(default = 0.25)]
|
|
186
183
|
pub mem_output_threshold: f64,
|
|
187
184
|
/// See [pid::Pid::d]
|
|
188
|
-
#[builder(default =
|
|
185
|
+
#[builder(default = 5.0)]
|
|
189
186
|
pub cpu_p_gain: f64,
|
|
190
187
|
/// See [pid::Pid::i]
|
|
191
|
-
#[builder(default =
|
|
188
|
+
#[builder(default = 0.0)]
|
|
192
189
|
pub cpu_i_gain: f64,
|
|
193
190
|
/// See [pid::Pid::d]
|
|
194
|
-
#[builder(default =
|
|
191
|
+
#[builder(default = 1.0)]
|
|
195
192
|
pub cpu_d_gain: f64,
|
|
196
193
|
/// If the CPU PID controller outputs a value higher than this, we say the CPU half of things
|
|
197
194
|
/// will allow a slot
|
|
198
|
-
#[builder(default =
|
|
195
|
+
#[builder(default = 0.05)]
|
|
199
196
|
pub cpu_output_threshold: f64,
|
|
200
197
|
}
|
|
201
198
|
struct PidControllers {
|
|
@@ -237,7 +234,7 @@ impl MetricInstruments {
|
|
|
237
234
|
let cpu_usage = meter.gauge_f64("resource_slots_cpu_usage".into());
|
|
238
235
|
let mem_pid_output = meter.gauge_f64("resource_slots_mem_pid_output".into());
|
|
239
236
|
let cpu_pid_output = meter.gauge_f64("resource_slots_cpu_pid_output".into());
|
|
240
|
-
let attribs = meter.
|
|
237
|
+
let attribs = meter.get_default_attributes().clone();
|
|
241
238
|
Self {
|
|
242
239
|
attribs,
|
|
243
240
|
mem_usage,
|
|
@@ -727,7 +724,10 @@ impl CGroupCpuFileSystem for CgroupV2CpuFileSystem {
|
|
|
727
724
|
#[cfg(test)]
|
|
728
725
|
mod tests {
|
|
729
726
|
use super::*;
|
|
730
|
-
use crate::{
|
|
727
|
+
use crate::{
|
|
728
|
+
abstractions::MeteredPermitDealer, telemetry::metrics::MetricsContext,
|
|
729
|
+
worker::WorkflowSlotKind,
|
|
730
|
+
};
|
|
731
731
|
use std::{
|
|
732
732
|
cell::RefCell,
|
|
733
733
|
env,
|
|
@@ -739,7 +739,6 @@ mod tests {
|
|
|
739
739
|
},
|
|
740
740
|
thread::sleep,
|
|
741
741
|
};
|
|
742
|
-
use temporalio_common::worker::WorkflowSlotKind;
|
|
743
742
|
|
|
744
743
|
struct FakeMIS {
|
|
745
744
|
used: Arc<AtomicU64>,
|
|
@@ -765,11 +764,10 @@ mod tests {
|
|
|
765
764
|
}
|
|
766
765
|
|
|
767
766
|
fn test_options() -> ResourceBasedSlotsOptions {
|
|
768
|
-
|
|
767
|
+
ResourceBasedSlotsOptions::builder()
|
|
769
768
|
.target_mem_usage(0.8)
|
|
770
769
|
.target_cpu_usage(1.0)
|
|
771
770
|
.build()
|
|
772
|
-
.expect("default resource based slot options can't fail to build")
|
|
773
771
|
}
|
|
774
772
|
|
|
775
773
|
#[test]
|
|
@@ -9,13 +9,16 @@ pub use resource_based::{
|
|
|
9
9
|
|
|
10
10
|
pub(crate) use resource_based::{RealSysInfo, SystemResourceInfo};
|
|
11
11
|
|
|
12
|
-
use
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
use crate::{
|
|
13
|
+
WorkerConfig,
|
|
14
|
+
worker::{
|
|
15
|
+
ActivitySlotKind, LocalActivitySlotKind, NexusSlotKind, SlotKind, SlotSupplier,
|
|
16
|
+
WorkerTuner, WorkflowSlotKind,
|
|
17
|
+
},
|
|
16
18
|
};
|
|
19
|
+
use std::sync::Arc;
|
|
17
20
|
|
|
18
|
-
/// Allows for the composition of different slot suppliers into a [WorkerTuner]
|
|
21
|
+
/// Allows for the composition of different slot suppliers into a [crate::WorkerTuner]
|
|
19
22
|
pub struct TunerHolder {
|
|
20
23
|
wft_supplier: Arc<dyn SlotSupplier<SlotKind = WorkflowSlotKind> + Send + Sync>,
|
|
21
24
|
act_supplier: Arc<dyn SlotSupplier<SlotKind = ActivitySlotKind> + Send + Sync>,
|
|
@@ -23,27 +26,39 @@ pub struct TunerHolder {
|
|
|
23
26
|
nexus_supplier: Arc<dyn SlotSupplier<SlotKind = NexusSlotKind> + Send + Sync>,
|
|
24
27
|
}
|
|
25
28
|
|
|
29
|
+
impl TunerHolder {
|
|
30
|
+
/// Create a tuner with fixed size slot suppliers for all slot kinds.
|
|
31
|
+
pub fn fixed_size(
|
|
32
|
+
workflow_slots: usize,
|
|
33
|
+
activity_slots: usize,
|
|
34
|
+
local_activity_slots: usize,
|
|
35
|
+
nexus_slots: usize,
|
|
36
|
+
) -> Self {
|
|
37
|
+
Self {
|
|
38
|
+
wft_supplier: Arc::new(FixedSizeSlotSupplier::new(workflow_slots)),
|
|
39
|
+
act_supplier: Arc::new(FixedSizeSlotSupplier::new(activity_slots)),
|
|
40
|
+
la_supplier: Arc::new(FixedSizeSlotSupplier::new(local_activity_slots)),
|
|
41
|
+
nexus_supplier: Arc::new(FixedSizeSlotSupplier::new(nexus_slots)),
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
26
46
|
/// Can be used to construct a [TunerHolder] without needing to manually construct each
|
|
27
47
|
/// [SlotSupplier]. Useful for lang bridges to allow more easily passing through user options.
|
|
28
|
-
#[derive(Clone, Debug,
|
|
29
|
-
#[builder(
|
|
48
|
+
#[derive(Clone, Debug, bon::Builder)]
|
|
49
|
+
#[builder(finish_fn(vis = "", name = build_internal))]
|
|
30
50
|
#[non_exhaustive]
|
|
31
51
|
pub struct TunerHolderOptions {
|
|
32
52
|
/// Options for workflow slots
|
|
33
|
-
#[builder(default, setter(strip_option))]
|
|
34
53
|
pub workflow_slot_options: Option<SlotSupplierOptions<WorkflowSlotKind>>,
|
|
35
54
|
/// Options for activity slots
|
|
36
|
-
#[builder(default, setter(strip_option))]
|
|
37
55
|
pub activity_slot_options: Option<SlotSupplierOptions<ActivitySlotKind>>,
|
|
38
56
|
/// Options for local activity slots
|
|
39
|
-
#[builder(default, setter(strip_option))]
|
|
40
57
|
pub local_activity_slot_options: Option<SlotSupplierOptions<LocalActivitySlotKind>>,
|
|
41
58
|
/// Options for nexus slots
|
|
42
|
-
#[builder(default, setter(strip_option))]
|
|
43
59
|
pub nexus_slot_options: Option<SlotSupplierOptions<NexusSlotKind>>,
|
|
44
60
|
/// Options that will apply to all resource based slot suppliers. Must be set if any slot
|
|
45
61
|
/// options are [SlotSupplierOptions::ResourceBased]
|
|
46
|
-
#[builder(default, setter(strip_option))]
|
|
47
62
|
pub resource_based_options: Option<ResourceBasedSlotsOptions>,
|
|
48
63
|
}
|
|
49
64
|
|
|
@@ -150,35 +165,42 @@ pub enum SlotSupplierOptions<SK: SlotKind> {
|
|
|
150
165
|
Custom(Arc<dyn SlotSupplier<SlotKind = SK> + Send + Sync>),
|
|
151
166
|
}
|
|
152
167
|
|
|
153
|
-
impl TunerHolderOptionsBuilder {
|
|
168
|
+
impl<State: tuner_holder_options_builder::IsComplete> TunerHolderOptionsBuilder<State> {
|
|
169
|
+
/// Build the [TunerHolderOptions] with validation
|
|
170
|
+
pub fn build(self) -> Result<TunerHolderOptions, String> {
|
|
171
|
+
let options = self.build_internal();
|
|
172
|
+
validate_tuner_holder_options(&options)?;
|
|
173
|
+
Ok(options)
|
|
174
|
+
}
|
|
175
|
+
|
|
154
176
|
/// Create a [TunerHolder] from this builder
|
|
155
177
|
pub fn build_tuner_holder(self) -> Result<TunerHolder, anyhow::Error> {
|
|
156
|
-
let s = self.build()?;
|
|
178
|
+
let s = self.build().map_err(|e: String| anyhow::anyhow!(e))?;
|
|
157
179
|
s.build_tuner_holder()
|
|
158
180
|
}
|
|
181
|
+
}
|
|
159
182
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
183
|
+
fn validate_tuner_holder_options(options: &TunerHolderOptions) -> Result<(), String> {
|
|
184
|
+
let any_is_resource_based = matches!(
|
|
185
|
+
options.workflow_slot_options,
|
|
186
|
+
Some(SlotSupplierOptions::ResourceBased(_))
|
|
187
|
+
) || matches!(
|
|
188
|
+
options.activity_slot_options,
|
|
189
|
+
Some(SlotSupplierOptions::ResourceBased(_))
|
|
190
|
+
) || matches!(
|
|
191
|
+
options.local_activity_slot_options,
|
|
192
|
+
Some(SlotSupplierOptions::ResourceBased(_))
|
|
193
|
+
) || matches!(
|
|
194
|
+
options.nexus_slot_options,
|
|
195
|
+
Some(SlotSupplierOptions::ResourceBased(_))
|
|
196
|
+
);
|
|
197
|
+
if any_is_resource_based && options.resource_based_options.is_none() {
|
|
198
|
+
return Err(
|
|
199
|
+
"`resource_based_options` must be set if any slot options are ResourceBased"
|
|
200
|
+
.to_string(),
|
|
173
201
|
);
|
|
174
|
-
if any_is_resource_based && matches!(self.resource_based_options, None | Some(None)) {
|
|
175
|
-
return Err(
|
|
176
|
-
"`resource_based_options` must be set if any slot options are ResourceBased"
|
|
177
|
-
.to_string(),
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
Ok(())
|
|
181
202
|
}
|
|
203
|
+
Ok(())
|
|
182
204
|
}
|
|
183
205
|
|
|
184
206
|
/// Can be used to construct a `TunerHolder` from individual slot suppliers. Any supplier which is
|
|
@@ -260,7 +282,7 @@ impl TunerBuilder {
|
|
|
260
282
|
self.sys_info.clone()
|
|
261
283
|
}
|
|
262
284
|
|
|
263
|
-
/// Build a [WorkerTuner] from the configured slot suppliers
|
|
285
|
+
/// Build a [crate::WorkerTuner] from the configured slot suppliers
|
|
264
286
|
pub fn build(&mut self) -> TunerHolder {
|
|
265
287
|
TunerHolder {
|
|
266
288
|
wft_supplier: self
|
|
@@ -312,10 +334,10 @@ impl WorkerTuner for TunerHolder {
|
|
|
312
334
|
#[cfg(test)]
|
|
313
335
|
mod tests {
|
|
314
336
|
use super::*;
|
|
315
|
-
use
|
|
316
|
-
use temporalio_common::worker::{
|
|
337
|
+
use crate::worker::{
|
|
317
338
|
SlotMarkUsedContext, SlotReleaseContext, SlotReservationContext, SlotSupplierPermit,
|
|
318
339
|
};
|
|
340
|
+
use std::time::Duration;
|
|
319
341
|
|
|
320
342
|
struct TestSlotSupplier;
|
|
321
343
|
#[async_trait::async_trait]
|
|
@@ -348,11 +370,10 @@ mod tests {
|
|
|
348
370
|
|
|
349
371
|
#[test]
|
|
350
372
|
fn tuner_holder_options_nexus_resource_based() {
|
|
351
|
-
let resource_opts =
|
|
373
|
+
let resource_opts = ResourceBasedSlotsOptions::builder()
|
|
352
374
|
.target_mem_usage(0.8)
|
|
353
375
|
.target_cpu_usage(0.9)
|
|
354
|
-
.build()
|
|
355
|
-
.unwrap();
|
|
376
|
+
.build();
|
|
356
377
|
|
|
357
378
|
let options = TunerHolderOptions {
|
|
358
379
|
workflow_slot_options: None,
|
|
@@ -403,7 +424,7 @@ mod tests {
|
|
|
403
424
|
#[test]
|
|
404
425
|
fn tuner_holder_options_builder_validates_resource_based_requirements() {
|
|
405
426
|
// Should fail when nexus uses ResourceBased but resource_based_options is not set
|
|
406
|
-
let result =
|
|
427
|
+
let result = TunerHolderOptions::builder()
|
|
407
428
|
.nexus_slot_options(SlotSupplierOptions::ResourceBased(
|
|
408
429
|
ResourceSlotOptions::new(5, 100, Duration::from_millis(100)),
|
|
409
430
|
))
|
|
@@ -420,11 +441,10 @@ mod tests {
|
|
|
420
441
|
|
|
421
442
|
#[test]
|
|
422
443
|
fn tuner_holder_options_all_slot_types() {
|
|
423
|
-
let resource_opts =
|
|
444
|
+
let resource_opts = ResourceBasedSlotsOptions::builder()
|
|
424
445
|
.target_mem_usage(0.8)
|
|
425
446
|
.target_cpu_usage(0.9)
|
|
426
|
-
.build()
|
|
427
|
-
.unwrap();
|
|
447
|
+
.build();
|
|
428
448
|
|
|
429
449
|
let options = TunerHolderOptions {
|
|
430
450
|
workflow_slot_options: Some(SlotSupplierOptions::FixedSize { slots: 10 }),
|
|
@@ -9,7 +9,10 @@ use std::{
|
|
|
9
9
|
};
|
|
10
10
|
use temporalio_common::protos::{
|
|
11
11
|
coresdk::workflow_activation::{WorkflowActivationJob, start_workflow_from_attribs},
|
|
12
|
-
temporal::api::{
|
|
12
|
+
temporal::api::{
|
|
13
|
+
common::v1::{Payload, SearchAttributes},
|
|
14
|
+
history::v1::WorkflowExecutionStartedEventAttributes,
|
|
15
|
+
},
|
|
13
16
|
utilities::TryIntoOrNone,
|
|
14
17
|
};
|
|
15
18
|
|
|
@@ -97,8 +100,11 @@ impl DrivenWorkflow {
|
|
|
97
100
|
}
|
|
98
101
|
|
|
99
102
|
/// Lang sent us an SA upsert command - use it to update our current view of search attributes.
|
|
100
|
-
pub(crate) fn search_attributes_update(&mut self, update:
|
|
101
|
-
|
|
103
|
+
pub(crate) fn search_attributes_update(&mut self, update: Option<SearchAttributes>) {
|
|
104
|
+
if let Some(sa) = update {
|
|
105
|
+
self.search_attribute_modifications
|
|
106
|
+
.extend(sa.indexed_fields);
|
|
107
|
+
}
|
|
102
108
|
}
|
|
103
109
|
|
|
104
110
|
/// Return a view of the "current" state of search attributes. IE: The initial attributes
|