@temporalio/core-bridge 1.15.0 → 1.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +172 -70
- package/lib/native.d.ts +1 -1
- package/package.json +2 -2
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/releases/x86_64-apple-darwin/index.node +0 -0
- package/releases/x86_64-pc-windows-msvc/index.node +0 -0
- package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
- package/sdk-core/.github/workflows/per-pr.yml +6 -6
- package/sdk-core/AGENTS.md +41 -30
- package/sdk-core/Cargo.toml +3 -0
- package/sdk-core/README.md +15 -9
- package/sdk-core/crates/client/Cargo.toml +4 -0
- package/sdk-core/crates/client/README.md +139 -0
- package/sdk-core/crates/client/src/async_activity_handle.rs +297 -0
- package/sdk-core/crates/client/src/callback_based.rs +7 -0
- package/sdk-core/crates/client/src/errors.rs +294 -0
- package/sdk-core/crates/client/src/{raw.rs → grpc.rs} +280 -159
- package/sdk-core/crates/client/src/lib.rs +920 -1326
- package/sdk-core/crates/client/src/metrics.rs +24 -33
- package/sdk-core/crates/client/src/options_structs.rs +457 -0
- package/sdk-core/crates/client/src/replaceable.rs +5 -4
- package/sdk-core/crates/client/src/request_extensions.rs +8 -9
- package/sdk-core/crates/client/src/retry.rs +99 -54
- package/sdk-core/crates/client/src/{worker/mod.rs → worker.rs} +1 -1
- package/sdk-core/crates/client/src/workflow_handle.rs +826 -0
- package/sdk-core/crates/common/Cargo.toml +61 -2
- package/sdk-core/crates/common/build.rs +742 -12
- package/sdk-core/crates/common/protos/api_upstream/.github/workflows/ci.yml +2 -0
- package/sdk-core/crates/common/protos/api_upstream/Makefile +2 -1
- package/sdk-core/crates/common/protos/api_upstream/buf.yaml +0 -3
- package/sdk-core/crates/common/protos/api_upstream/cmd/check-path-conflicts/main.go +137 -0
- package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv2.json +1166 -770
- package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv3.yaml +1243 -750
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/deployment/v1/message.proto +2 -2
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/workflow.proto +4 -3
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/failure/v1/message.proto +1 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/history/v1/message.proto +4 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/nexus/v1/message.proto +16 -1
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +64 -6
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +88 -33
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/nexus/nexus.proto +4 -2
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +4 -0
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +5 -5
- package/sdk-core/crates/common/src/activity_definition.rs +20 -0
- package/sdk-core/crates/common/src/data_converters.rs +770 -0
- package/sdk-core/crates/common/src/envconfig.rs +5 -0
- package/sdk-core/crates/common/src/lib.rs +15 -211
- package/sdk-core/crates/common/src/payload_visitor.rs +648 -0
- package/sdk-core/crates/common/src/priority.rs +110 -0
- package/sdk-core/crates/common/src/protos/canned_histories.rs +3 -0
- package/sdk-core/crates/common/src/protos/history_builder.rs +45 -0
- package/sdk-core/crates/common/src/protos/history_info.rs +2 -0
- package/sdk-core/crates/common/src/protos/mod.rs +122 -27
- package/sdk-core/crates/common/src/protos/task_token.rs +3 -3
- package/sdk-core/crates/common/src/protos/utilities.rs +11 -0
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/log_export.rs +5 -7
- package/sdk-core/crates/common/src/telemetry/metrics/core.rs +125 -0
- package/sdk-core/crates/common/src/telemetry/metrics.rs +268 -223
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/otel.rs +8 -13
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_meter.rs +49 -50
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_server.rs +2 -3
- package/sdk-core/crates/common/src/telemetry.rs +264 -4
- package/sdk-core/crates/common/src/worker.rs +68 -603
- package/sdk-core/crates/common/src/workflow_definition.rs +60 -0
- package/sdk-core/crates/macros/Cargo.toml +5 -1
- package/sdk-core/crates/macros/src/activities_definitions.rs +585 -0
- package/sdk-core/crates/macros/src/fsm_impl.rs +507 -0
- package/sdk-core/crates/macros/src/lib.rs +138 -512
- package/sdk-core/crates/macros/src/macro_utils.rs +106 -0
- package/sdk-core/crates/macros/src/workflow_definitions.rs +1224 -0
- package/sdk-core/crates/sdk/Cargo.toml +19 -6
- package/sdk-core/crates/sdk/README.md +415 -0
- package/sdk-core/crates/sdk/src/activities.rs +417 -0
- package/sdk-core/crates/sdk/src/interceptors.rs +1 -1
- package/sdk-core/crates/sdk/src/lib.rs +757 -442
- package/sdk-core/crates/sdk/src/workflow_context/options.rs +45 -35
- package/sdk-core/crates/sdk/src/workflow_context.rs +1033 -289
- package/sdk-core/crates/sdk/src/workflow_future.rs +277 -213
- package/sdk-core/crates/sdk/src/workflows.rs +711 -0
- package/sdk-core/crates/sdk-core/Cargo.toml +57 -64
- package/sdk-core/crates/sdk-core/benches/workflow_replay_bench.rs +41 -35
- package/sdk-core/crates/sdk-core/machine_coverage/ActivityMachine_Coverage.puml +1 -1
- package/sdk-core/crates/sdk-core/src/abstractions.rs +6 -10
- package/sdk-core/crates/sdk-core/src/core_tests/activity_tasks.rs +6 -5
- package/sdk-core/crates/sdk-core/src/core_tests/mod.rs +13 -15
- package/sdk-core/crates/sdk-core/src/core_tests/queries.rs +21 -25
- package/sdk-core/crates/sdk-core/src/core_tests/replay_flag.rs +7 -10
- package/sdk-core/crates/sdk-core/src/core_tests/updates.rs +14 -17
- package/sdk-core/crates/sdk-core/src/core_tests/workers.rs +493 -26
- package/sdk-core/crates/sdk-core/src/core_tests/workflow_tasks.rs +4 -8
- package/sdk-core/crates/sdk-core/src/ephemeral_server/mod.rs +7 -7
- package/sdk-core/crates/sdk-core/src/histfetch.rs +20 -10
- package/sdk-core/crates/sdk-core/src/lib.rs +41 -111
- package/sdk-core/crates/sdk-core/src/pollers/mod.rs +4 -9
- package/sdk-core/crates/sdk-core/src/pollers/poll_buffer.rs +118 -19
- package/sdk-core/crates/sdk-core/src/protosext/mod.rs +2 -2
- package/sdk-core/crates/sdk-core/src/replay/mod.rs +14 -5
- package/sdk-core/crates/sdk-core/src/telemetry/metrics.rs +179 -196
- package/sdk-core/crates/sdk-core/src/telemetry/mod.rs +3 -280
- package/sdk-core/crates/sdk-core/src/test_help/integ_helpers.rs +6 -9
- package/sdk-core/crates/sdk-core/src/test_help/unit_helpers.rs +3 -6
- package/sdk-core/crates/sdk-core/src/worker/activities/local_activities.rs +11 -14
- package/sdk-core/crates/sdk-core/src/worker/activities.rs +16 -19
- package/sdk-core/crates/sdk-core/src/worker/client/mocks.rs +9 -5
- package/sdk-core/crates/sdk-core/src/worker/client.rs +103 -81
- package/sdk-core/crates/sdk-core/src/worker/heartbeat.rs +7 -11
- package/sdk-core/crates/sdk-core/src/worker/mod.rs +1124 -229
- package/sdk-core/crates/sdk-core/src/worker/nexus.rs +145 -23
- package/sdk-core/crates/sdk-core/src/worker/slot_provider.rs +2 -2
- package/sdk-core/crates/sdk-core/src/worker/tuner/fixed_size.rs +2 -2
- package/sdk-core/crates/sdk-core/src/worker/tuner/resource_based.rs +13 -13
- package/sdk-core/crates/sdk-core/src/worker/tuner.rs +28 -8
- package/sdk-core/crates/sdk-core/src/worker/workflow/driven_workflow.rs +9 -3
- package/sdk-core/crates/sdk-core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +21 -22
- package/sdk-core/crates/sdk-core/src/worker/workflow/machines/workflow_machines.rs +19 -4
- package/sdk-core/crates/sdk-core/src/worker/workflow/managed_run.rs +14 -18
- package/sdk-core/crates/sdk-core/src/worker/workflow/mod.rs +4 -6
- package/sdk-core/crates/sdk-core/src/worker/workflow/run_cache.rs +4 -7
- package/sdk-core/crates/sdk-core/src/worker/workflow/wft_extraction.rs +2 -4
- package/sdk-core/crates/sdk-core/src/worker/workflow/wft_poller.rs +8 -9
- package/sdk-core/crates/sdk-core/src/worker/workflow/workflow_stream.rs +1 -3
- package/sdk-core/crates/sdk-core/tests/activities_procmacro.rs +6 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/basic_pass.rs +54 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.rs +18 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.rs +14 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/multi_arg_pass.rs +48 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_input_pass.rs +14 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_return_type_pass.rs +19 -0
- package/sdk-core/crates/sdk-core/tests/cloud_tests.rs +14 -5
- package/sdk-core/crates/sdk-core/tests/common/activity_functions.rs +55 -0
- package/sdk-core/crates/sdk-core/tests/common/mod.rs +241 -196
- package/sdk-core/crates/sdk-core/tests/common/workflows.rs +41 -28
- package/sdk-core/crates/sdk-core/tests/global_metric_tests.rs +3 -5
- package/sdk-core/crates/sdk-core/tests/heavy_tests/fuzzy_workflow.rs +73 -64
- package/sdk-core/crates/sdk-core/tests/heavy_tests.rs +298 -252
- package/sdk-core/crates/sdk-core/tests/integ_tests/async_activity_client_tests.rs +230 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/client_tests.rs +94 -57
- package/sdk-core/crates/sdk-core/tests/integ_tests/data_converter_tests.rs +381 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +16 -12
- package/sdk-core/crates/sdk-core/tests/integ_tests/heartbeat_tests.rs +48 -40
- package/sdk-core/crates/sdk-core/tests/integ_tests/metrics_tests.rs +327 -255
- package/sdk-core/crates/sdk-core/tests/integ_tests/pagination_tests.rs +50 -45
- package/sdk-core/crates/sdk-core/tests/integ_tests/polling_tests.rs +147 -126
- package/sdk-core/crates/sdk-core/tests/integ_tests/queries_tests.rs +103 -89
- package/sdk-core/crates/sdk-core/tests/integ_tests/update_tests.rs +609 -453
- package/sdk-core/crates/sdk-core/tests/integ_tests/visibility_tests.rs +80 -62
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_heartbeat_tests.rs +360 -231
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_tests.rs +248 -185
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_versioning_tests.rs +52 -43
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_client_tests.rs +180 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/activities.rs +428 -315
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +82 -56
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +56 -28
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +364 -243
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/client_interactions.rs +552 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +101 -42
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +243 -147
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/eager.rs +98 -28
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +1475 -1036
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +73 -41
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +397 -238
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/patches.rs +414 -189
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/queries.rs +415 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/replay.rs +96 -36
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/resets.rs +154 -137
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/signals.rs +183 -105
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +85 -38
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/timers.rs +142 -40
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +73 -54
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests.rs +363 -226
- package/sdk-core/crates/sdk-core/tests/main.rs +17 -15
- package/sdk-core/crates/sdk-core/tests/manual_tests.rs +207 -152
- package/sdk-core/crates/sdk-core/tests/shared_tests/mod.rs +65 -34
- package/sdk-core/crates/sdk-core/tests/shared_tests/priority.rs +107 -84
- package/sdk-core/crates/sdk-core/tests/workflows_procmacro.rs +6 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.rs +26 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/basic_pass.rs +49 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/minimal_pass.rs +21 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.rs +26 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.rs +21 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core-c-bridge/Cargo.toml +7 -1
- package/sdk-core/crates/sdk-core-c-bridge/include/temporal-sdk-core-c-bridge.h +14 -14
- package/sdk-core/crates/sdk-core-c-bridge/src/client.rs +83 -74
- package/sdk-core/crates/sdk-core-c-bridge/src/metric.rs +9 -14
- package/sdk-core/crates/sdk-core-c-bridge/src/runtime.rs +1 -2
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/context.rs +13 -13
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/mod.rs +6 -6
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/utils.rs +3 -4
- package/sdk-core/crates/sdk-core-c-bridge/src/worker.rs +62 -75
- package/sdk-core/rustfmt.toml +2 -1
- package/src/client.rs +205 -318
- package/src/metrics.rs +22 -30
- package/src/runtime.rs +4 -5
- package/src/worker.rs +16 -19
- package/ts/native.ts +1 -1
- package/sdk-core/crates/client/src/workflow_handle/mod.rs +0 -212
- package/sdk-core/crates/common/src/errors.rs +0 -85
- package/sdk-core/crates/common/tests/worker_task_types_test.rs +0 -129
- package/sdk-core/crates/sdk/src/activity_context.rs +0 -238
- package/sdk-core/crates/sdk/src/app_data.rs +0 -37
- package/sdk-core/crates/sdk-core/tests/integ_tests/activity_functions.rs +0 -5
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +0 -61
|
@@ -1,22 +1,15 @@
|
|
|
1
1
|
//! Contains types that are needed by both the client and the sdk when configuring / interacting
|
|
2
2
|
//! with workers.
|
|
3
3
|
|
|
4
|
-
use crate::{
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
coresdk,
|
|
8
|
-
coresdk::{ActivitySlotInfo, LocalActivitySlotInfo, NexusSlotInfo, WorkflowSlotInfo},
|
|
9
|
-
temporal,
|
|
10
|
-
temporal::api::{enums::v1::VersioningBehavior, worker::v1::PluginInfo},
|
|
11
|
-
},
|
|
12
|
-
telemetry::metrics::TemporalMeter,
|
|
4
|
+
use crate::protos::{
|
|
5
|
+
coresdk, temporal,
|
|
6
|
+
temporal::api::enums::v1::{TaskQueueType, VersioningBehavior},
|
|
13
7
|
};
|
|
14
8
|
use std::{
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
fs::File,
|
|
10
|
+
io::{self, BufReader, Read},
|
|
17
11
|
str::FromStr,
|
|
18
|
-
sync::
|
|
19
|
-
time::Duration,
|
|
12
|
+
sync::OnceLock,
|
|
20
13
|
};
|
|
21
14
|
|
|
22
15
|
/// Specifies which task types a worker will poll for.
|
|
@@ -24,9 +17,13 @@ use std::{
|
|
|
24
17
|
/// Workers can be configured to handle any combination of workflows, activities, and nexus operations.
|
|
25
18
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
|
26
19
|
pub struct WorkerTaskTypes {
|
|
20
|
+
/// Whether workflow tasks are enabled.
|
|
27
21
|
pub enable_workflows: bool,
|
|
22
|
+
/// Whether local activity tasks are enabled.
|
|
28
23
|
pub enable_local_activities: bool,
|
|
24
|
+
/// Whether remote activity tasks are enabled.
|
|
29
25
|
pub enable_remote_activities: bool,
|
|
26
|
+
/// Whether nexus tasks are enabled.
|
|
30
27
|
pub enable_nexus: bool,
|
|
31
28
|
}
|
|
32
29
|
|
|
@@ -79,609 +76,31 @@ impl WorkerTaskTypes {
|
|
|
79
76
|
}
|
|
80
77
|
}
|
|
81
78
|
|
|
79
|
+
/// Returns true if any task type is enabled in both configs.
|
|
82
80
|
pub fn overlaps_with(&self, other: &WorkerTaskTypes) -> bool {
|
|
83
81
|
(self.enable_workflows && other.enable_workflows)
|
|
84
82
|
|| (self.enable_local_activities && other.enable_local_activities)
|
|
85
83
|
|| (self.enable_remote_activities && other.enable_remote_activities)
|
|
86
84
|
|| (self.enable_nexus && other.enable_nexus)
|
|
87
85
|
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/// Defines per-worker configuration options
|
|
91
|
-
#[derive(Clone, bon::Builder)]
|
|
92
|
-
#[builder(on(String, into), state_mod(vis = "pub"), finish_fn(vis = "", name = build_internal))]
|
|
93
|
-
#[non_exhaustive]
|
|
94
|
-
pub struct WorkerConfig {
|
|
95
|
-
/// The Temporal service namespace this worker is bound to
|
|
96
|
-
pub namespace: String,
|
|
97
|
-
/// What task queue will this worker poll from? This task queue name will be used for both
|
|
98
|
-
/// workflow and activity polling.
|
|
99
|
-
pub task_queue: String,
|
|
100
|
-
/// A human-readable string that can identify this worker. Using something like sdk version
|
|
101
|
-
/// and host name is a good default. If set, overrides the identity set (if any) on the client
|
|
102
|
-
/// used by this worker.
|
|
103
|
-
pub client_identity_override: Option<String>,
|
|
104
|
-
/// If set nonzero, workflows will be cached and sticky task queues will be used, meaning that
|
|
105
|
-
/// history updates are applied incrementally to suspended instances of workflow execution.
|
|
106
|
-
/// Workflows are evicted according to a least-recently-used policy one the cache maximum is
|
|
107
|
-
/// reached. Workflows may also be explicitly evicted at any time, or as a result of errors
|
|
108
|
-
/// or failures.
|
|
109
|
-
#[builder(default = 0)]
|
|
110
|
-
pub max_cached_workflows: usize,
|
|
111
|
-
/// Set a [WorkerTuner] for this worker. Either this or at least one of the `max_outstanding_*`
|
|
112
|
-
/// fields must be set.
|
|
113
|
-
pub tuner: Option<Arc<dyn WorkerTuner + Send + Sync>>,
|
|
114
|
-
/// Maximum number of concurrent poll workflow task requests we will perform at a time on this
|
|
115
|
-
/// worker's task queue. See also [WorkerConfig::nonsticky_to_sticky_poll_ratio].
|
|
116
|
-
/// If using SimpleMaximum, Must be at least 2 when `max_cached_workflows` > 0, or is an error.
|
|
117
|
-
#[builder(default = PollerBehavior::SimpleMaximum(5))]
|
|
118
|
-
pub workflow_task_poller_behavior: PollerBehavior,
|
|
119
|
-
/// Only applies when using [PollerBehavior::SimpleMaximum]
|
|
120
|
-
///
|
|
121
|
-
/// (max workflow task polls * this number) = the number of max pollers that will be allowed for
|
|
122
|
-
/// the nonsticky queue when sticky tasks are enabled. If both defaults are used, the sticky
|
|
123
|
-
/// queue will allow 4 max pollers while the nonsticky queue will allow one. The minimum for
|
|
124
|
-
/// either poller is 1, so if the maximum allowed is 1 and sticky queues are enabled, there will
|
|
125
|
-
/// be 2 concurrent polls.
|
|
126
|
-
#[builder(default = 0.2)]
|
|
127
|
-
pub nonsticky_to_sticky_poll_ratio: f32,
|
|
128
|
-
/// Maximum number of concurrent poll activity task requests we will perform at a time on this
|
|
129
|
-
/// worker's task queue
|
|
130
|
-
#[builder(default = PollerBehavior::SimpleMaximum(5))]
|
|
131
|
-
pub activity_task_poller_behavior: PollerBehavior,
|
|
132
|
-
/// Maximum number of concurrent poll nexus task requests we will perform at a time on this
|
|
133
|
-
/// worker's task queue
|
|
134
|
-
#[builder(default = PollerBehavior::SimpleMaximum(5))]
|
|
135
|
-
pub nexus_task_poller_behavior: PollerBehavior,
|
|
136
|
-
/// Specifies which task types this worker will poll for.
|
|
137
|
-
///
|
|
138
|
-
/// Note: At least one task type must be specified or the worker will fail validation.
|
|
139
|
-
pub task_types: WorkerTaskTypes,
|
|
140
|
-
/// How long a workflow task is allowed to sit on the sticky queue before it is timed out
|
|
141
|
-
/// and moved to the non-sticky queue where it may be picked up by any worker.
|
|
142
|
-
#[builder(default = Duration::from_secs(10))]
|
|
143
|
-
pub sticky_queue_schedule_to_start_timeout: Duration,
|
|
144
|
-
|
|
145
|
-
/// Longest interval for throttling activity heartbeats
|
|
146
|
-
#[builder(default = Duration::from_secs(60))]
|
|
147
|
-
pub max_heartbeat_throttle_interval: Duration,
|
|
148
|
-
|
|
149
|
-
/// Default interval for throttling activity heartbeats in case
|
|
150
|
-
/// `ActivityOptions.heartbeat_timeout` is unset.
|
|
151
|
-
/// When the timeout *is* set in the `ActivityOptions`, throttling is set to
|
|
152
|
-
/// `heartbeat_timeout * 0.8`.
|
|
153
|
-
#[builder(default = Duration::from_secs(30))]
|
|
154
|
-
pub default_heartbeat_throttle_interval: Duration,
|
|
155
|
-
|
|
156
|
-
/// Sets the maximum number of activities per second the task queue will dispatch, controlled
|
|
157
|
-
/// server-side. Note that this only takes effect upon an activity poll request. If multiple
|
|
158
|
-
/// workers on the same queue have different values set, they will thrash with the last poller
|
|
159
|
-
/// winning.
|
|
160
|
-
///
|
|
161
|
-
/// Setting this to a nonzero value will also disable eager activity execution.
|
|
162
|
-
pub max_task_queue_activities_per_second: Option<f64>,
|
|
163
|
-
|
|
164
|
-
/// Limits the number of activities per second that this worker will process. The worker will
|
|
165
|
-
/// not poll for new activities if by doing so it might receive and execute an activity which
|
|
166
|
-
/// would cause it to exceed this limit. Negative, zero, or NaN values will cause building
|
|
167
|
-
/// the options to fail.
|
|
168
|
-
pub max_worker_activities_per_second: Option<f64>,
|
|
169
|
-
|
|
170
|
-
/// If set false (default), shutdown will not finish until all pending evictions have been
|
|
171
|
-
/// issued and replied to. If set true shutdown will be considered complete when the only
|
|
172
|
-
/// remaining work is pending evictions.
|
|
173
|
-
///
|
|
174
|
-
/// This flag is useful during tests to avoid needing to deal with lots of uninteresting
|
|
175
|
-
/// evictions during shutdown. Alternatively, if a lang implementation finds it easy to clean
|
|
176
|
-
/// up during shutdown, setting this true saves some back-and-forth.
|
|
177
|
-
#[builder(default = false)]
|
|
178
|
-
pub ignore_evicts_on_shutdown: bool,
|
|
179
|
-
|
|
180
|
-
/// Maximum number of next page (or initial) history event listing requests we'll make
|
|
181
|
-
/// concurrently. I don't this it's worth exposing this to users until we encounter a reason.
|
|
182
|
-
#[builder(default = 5)]
|
|
183
|
-
pub fetching_concurrency: usize,
|
|
184
|
-
|
|
185
|
-
/// If set, core will issue cancels for all outstanding activities and nexus operations after
|
|
186
|
-
/// shutdown has been initiated and this amount of time has elapsed.
|
|
187
|
-
pub graceful_shutdown_period: Option<Duration>,
|
|
188
|
-
|
|
189
|
-
/// The amount of time core will wait before timing out activities using its own local timers
|
|
190
|
-
/// after one of them elapses. This is to avoid racing with server's own tracking of the
|
|
191
|
-
/// timeout.
|
|
192
|
-
#[builder(default = Duration::from_secs(5))]
|
|
193
|
-
pub local_timeout_buffer_for_activities: Duration,
|
|
194
|
-
|
|
195
|
-
/// Any error types listed here will cause any workflow being processed by this worker to fail,
|
|
196
|
-
/// rather than simply failing the workflow task.
|
|
197
|
-
#[builder(default)]
|
|
198
|
-
pub workflow_failure_errors: HashSet<WorkflowErrorType>,
|
|
199
|
-
|
|
200
|
-
/// Like [WorkerConfig::workflow_failure_errors], but specific to certain workflow types (the
|
|
201
|
-
/// map key).
|
|
202
|
-
#[builder(default)]
|
|
203
|
-
pub workflow_types_to_failure_errors: HashMap<String, HashSet<WorkflowErrorType>>,
|
|
204
|
-
|
|
205
|
-
/// The maximum allowed number of workflow tasks that will ever be given to this worker at one
|
|
206
|
-
/// time. Note that one workflow task may require multiple activations - so the WFT counts as
|
|
207
|
-
/// "outstanding" until all activations it requires have been completed. Must be at least 2 if
|
|
208
|
-
/// `max_cached_workflows` is > 0, or is an error.
|
|
209
|
-
///
|
|
210
|
-
/// Mutually exclusive with `tuner`
|
|
211
|
-
#[builder(into)]
|
|
212
|
-
pub max_outstanding_workflow_tasks: Option<usize>,
|
|
213
|
-
/// The maximum number of activity tasks that will ever be given to this worker concurrently.
|
|
214
|
-
///
|
|
215
|
-
/// Mutually exclusive with `tuner`
|
|
216
|
-
#[builder(into)]
|
|
217
|
-
pub max_outstanding_activities: Option<usize>,
|
|
218
|
-
/// The maximum number of local activity tasks that will ever be given to this worker
|
|
219
|
-
/// concurrently.
|
|
220
|
-
///
|
|
221
|
-
/// Mutually exclusive with `tuner`
|
|
222
|
-
#[builder(into)]
|
|
223
|
-
pub max_outstanding_local_activities: Option<usize>,
|
|
224
|
-
/// The maximum number of nexus tasks that will ever be given to this worker
|
|
225
|
-
/// concurrently.
|
|
226
|
-
///
|
|
227
|
-
/// Mutually exclusive with `tuner`
|
|
228
|
-
#[builder(into)]
|
|
229
|
-
pub max_outstanding_nexus_tasks: Option<usize>,
|
|
230
|
-
|
|
231
|
-
/// A versioning strategy for this worker.
|
|
232
|
-
pub versioning_strategy: WorkerVersioningStrategy,
|
|
233
|
-
|
|
234
|
-
/// List of plugins used by lang.
|
|
235
|
-
#[builder(default)]
|
|
236
|
-
pub plugins: HashSet<PluginInfo>,
|
|
237
|
-
|
|
238
|
-
/// Skips the single worker+client+namespace+task_queue check
|
|
239
|
-
#[builder(default = false)]
|
|
240
|
-
pub skip_client_worker_set_check: bool,
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
impl WorkerConfig {
|
|
244
|
-
/// Returns true if the configuration specifies we should fail a workflow on a certain error
|
|
245
|
-
/// type rather than failing the workflow task.
|
|
246
|
-
pub fn should_fail_workflow(
|
|
247
|
-
&self,
|
|
248
|
-
workflow_type: &str,
|
|
249
|
-
error_type: &WorkflowErrorType,
|
|
250
|
-
) -> bool {
|
|
251
|
-
self.workflow_failure_errors.contains(error_type)
|
|
252
|
-
|| self
|
|
253
|
-
.workflow_types_to_failure_errors
|
|
254
|
-
.get(workflow_type)
|
|
255
|
-
.map(|s| s.contains(error_type))
|
|
256
|
-
.unwrap_or(false)
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
pub fn computed_deployment_version(&self) -> Option<WorkerDeploymentVersion> {
|
|
260
|
-
let wdv = match self.versioning_strategy {
|
|
261
|
-
WorkerVersioningStrategy::None { ref build_id } => WorkerDeploymentVersion {
|
|
262
|
-
deployment_name: "".to_owned(),
|
|
263
|
-
build_id: build_id.clone(),
|
|
264
|
-
},
|
|
265
|
-
WorkerVersioningStrategy::WorkerDeploymentBased(ref opts) => opts.version.clone(),
|
|
266
|
-
WorkerVersioningStrategy::LegacyBuildIdBased { ref build_id } => {
|
|
267
|
-
WorkerDeploymentVersion {
|
|
268
|
-
deployment_name: "".to_owned(),
|
|
269
|
-
build_id: build_id.clone(),
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
};
|
|
273
|
-
if wdv.is_empty() { None } else { Some(wdv) }
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
impl<S: worker_config_builder::IsComplete> WorkerConfigBuilder<S> {
|
|
278
|
-
pub fn build(self) -> Result<WorkerConfig, String> {
|
|
279
|
-
let config = self.build_internal();
|
|
280
|
-
let task_types = &config.task_types;
|
|
281
|
-
if task_types.is_empty() {
|
|
282
|
-
return Err("At least one task type must be enabled in `task_types`".to_string());
|
|
283
|
-
}
|
|
284
|
-
if !task_types.enable_workflows && task_types.enable_local_activities {
|
|
285
|
-
return Err(
|
|
286
|
-
"`task_types` cannot enable local activities without workflows".to_string(),
|
|
287
|
-
);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
config.workflow_task_poller_behavior.validate()?;
|
|
291
|
-
config.activity_task_poller_behavior.validate()?;
|
|
292
|
-
config.nexus_task_poller_behavior.validate()?;
|
|
293
|
-
|
|
294
|
-
if let Some(ref x) = config.max_worker_activities_per_second
|
|
295
|
-
&& (!x.is_normal() || x.is_sign_negative())
|
|
296
|
-
{
|
|
297
|
-
return Err(
|
|
298
|
-
"`max_worker_activities_per_second` must be positive and nonzero".to_string(),
|
|
299
|
-
);
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
if matches!(config.max_outstanding_workflow_tasks, Some(v) if v == 0) {
|
|
303
|
-
return Err("`max_outstanding_workflow_tasks` must be > 0".to_string());
|
|
304
|
-
}
|
|
305
|
-
if matches!(config.max_outstanding_activities, Some(v) if v == 0) {
|
|
306
|
-
return Err("`max_outstanding_activities` must be > 0".to_string());
|
|
307
|
-
}
|
|
308
|
-
if matches!(config.max_outstanding_local_activities, Some(v) if v == 0) {
|
|
309
|
-
return Err("`max_outstanding_local_activities` must be > 0".to_string());
|
|
310
|
-
}
|
|
311
|
-
if matches!(config.max_outstanding_nexus_tasks, Some(v) if v == 0) {
|
|
312
|
-
return Err("`max_outstanding_nexus_tasks` must be > 0".to_string());
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
if config.max_cached_workflows > 0 {
|
|
316
|
-
if let Some(max_wft) = config.max_outstanding_workflow_tasks
|
|
317
|
-
&& max_wft < 2
|
|
318
|
-
{
|
|
319
|
-
return Err(
|
|
320
|
-
"`max_cached_workflows` > 0 requires `max_outstanding_workflow_tasks` >= 2"
|
|
321
|
-
.to_string(),
|
|
322
|
-
);
|
|
323
|
-
}
|
|
324
|
-
if matches!(config.workflow_task_poller_behavior, PollerBehavior::SimpleMaximum(u) if u < 2)
|
|
325
|
-
{
|
|
326
|
-
return Err("`max_cached_workflows` > 0 requires `workflow_task_poller_behavior` to be at least 2".to_string());
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
if config.tuner.is_some()
|
|
331
|
-
&& (config.max_outstanding_workflow_tasks.is_some()
|
|
332
|
-
|| config.max_outstanding_activities.is_some()
|
|
333
|
-
|| config.max_outstanding_local_activities.is_some())
|
|
334
|
-
{
|
|
335
|
-
return Err("max_outstanding_* fields are mutually exclusive with `tuner`".to_string());
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
match &config.versioning_strategy {
|
|
339
|
-
WorkerVersioningStrategy::None { .. } => {}
|
|
340
|
-
WorkerVersioningStrategy::WorkerDeploymentBased(d) => {
|
|
341
|
-
if d.use_worker_versioning
|
|
342
|
-
&& (d.version.build_id.is_empty() || d.version.deployment_name.is_empty())
|
|
343
|
-
{
|
|
344
|
-
return Err("WorkerDeploymentVersion must have a non-empty build_id and deployment_name when deployment-based versioning is enabled".to_string());
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
WorkerVersioningStrategy::LegacyBuildIdBased { build_id } => {
|
|
348
|
-
if build_id.is_empty() {
|
|
349
|
-
return Err(
|
|
350
|
-
"Legacy build id-based versioning must have a non-empty build_id"
|
|
351
|
-
.to_string(),
|
|
352
|
-
);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
Ok(config)
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/// This trait allows users to customize the performance characteristics of workers dynamically.
|
|
362
|
-
/// For more, see the docstrings of the traits in the return types of its functions.
|
|
363
|
-
pub trait WorkerTuner {
|
|
364
|
-
/// Return a [SlotSupplier] for workflow tasks. Note that workflow task slot suppliers must be
|
|
365
|
-
/// willing to hand out a minimum of one non-sticky slot and one sticky slot if workflow caching
|
|
366
|
-
/// is enabled, otherwise the worker may fail to process new tasks.
|
|
367
|
-
fn workflow_task_slot_supplier(
|
|
368
|
-
&self,
|
|
369
|
-
) -> Arc<dyn SlotSupplier<SlotKind = WorkflowSlotKind> + Send + Sync>;
|
|
370
|
-
|
|
371
|
-
/// Return a [SlotSupplier] for activity tasks
|
|
372
|
-
fn activity_task_slot_supplier(
|
|
373
|
-
&self,
|
|
374
|
-
) -> Arc<dyn SlotSupplier<SlotKind = ActivitySlotKind> + Send + Sync>;
|
|
375
|
-
|
|
376
|
-
/// Return a [SlotSupplier] for local activities
|
|
377
|
-
fn local_activity_slot_supplier(
|
|
378
|
-
&self,
|
|
379
|
-
) -> Arc<dyn SlotSupplier<SlotKind = LocalActivitySlotKind> + Send + Sync>;
|
|
380
|
-
|
|
381
|
-
/// Return a [SlotSupplier] for nexus tasks
|
|
382
|
-
fn nexus_task_slot_supplier(
|
|
383
|
-
&self,
|
|
384
|
-
) -> Arc<dyn SlotSupplier<SlotKind = NexusSlotKind> + Send + Sync>;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
/// Implementing this trait allows users to customize how many tasks of certain kinds the worker
|
|
388
|
-
/// will perform concurrently.
|
|
389
|
-
///
|
|
390
|
-
/// Note that, for implementations on workflow tasks ([WorkflowSlotKind]), workers that have the
|
|
391
|
-
/// workflow cache enabled should be willing to hand out _at least_ two slots, to avoid the worker
|
|
392
|
-
/// becoming stuck only polling on the worker's sticky queue.
|
|
393
|
-
#[async_trait::async_trait]
|
|
394
|
-
pub trait SlotSupplier {
|
|
395
|
-
type SlotKind: SlotKind;
|
|
396
|
-
/// Block until a slot is available, then return a permit for the slot.
|
|
397
|
-
async fn reserve_slot(&self, ctx: &dyn SlotReservationContext) -> SlotSupplierPermit;
|
|
398
|
-
|
|
399
|
-
/// Try to immediately reserve a slot, returning None if one is not available. Implementations
|
|
400
|
-
/// must not block, or risk blocking the async event loop.
|
|
401
|
-
fn try_reserve_slot(&self, ctx: &dyn SlotReservationContext) -> Option<SlotSupplierPermit>;
|
|
402
|
-
|
|
403
|
-
/// Marks a slot as actually now being used. This is separate from reserving one because the
|
|
404
|
-
/// pollers need to reserve a slot before they have actually obtained work from server. Once
|
|
405
|
-
/// that task is obtained (and validated) then the slot can actually be used to work on the
|
|
406
|
-
/// task.
|
|
407
|
-
///
|
|
408
|
-
/// Users' implementation of this can choose to emit metrics, or otherwise leverage the
|
|
409
|
-
/// information provided by the `info` parameter to be better able to make future decisions
|
|
410
|
-
/// about whether a slot should be handed out.
|
|
411
|
-
fn mark_slot_used(&self, ctx: &dyn SlotMarkUsedContext<SlotKind = Self::SlotKind>);
|
|
412
|
-
|
|
413
|
-
/// Frees a slot.
|
|
414
|
-
fn release_slot(&self, ctx: &dyn SlotReleaseContext<SlotKind = Self::SlotKind>);
|
|
415
|
-
|
|
416
|
-
/// If this implementation knows how many slots are available at any moment, it should return
|
|
417
|
-
/// that here.
|
|
418
|
-
fn available_slots(&self) -> Option<usize> {
|
|
419
|
-
None
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
/// Returns a human-friendly identifier describing this supplier implementation for
|
|
423
|
-
/// diagnostics and telemetry.
|
|
424
|
-
fn slot_supplier_kind(&self) -> String {
|
|
425
|
-
"Custom".to_string()
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
pub trait SlotReservationContext: Send + Sync {
|
|
430
|
-
/// Returns the name of the task queue this worker is polling
|
|
431
|
-
fn task_queue(&self) -> &str;
|
|
432
|
-
|
|
433
|
-
/// Returns the identity of the worker
|
|
434
|
-
fn worker_identity(&self) -> &str;
|
|
435
|
-
|
|
436
|
-
/// Returns the deployment version of the worker, if one is set.
|
|
437
|
-
fn worker_deployment_version(&self) -> &Option<WorkerDeploymentVersion>;
|
|
438
|
-
|
|
439
|
-
/// Returns the number of currently outstanding slot permits, whether used or un-used.
|
|
440
|
-
fn num_issued_slots(&self) -> usize;
|
|
441
|
-
|
|
442
|
-
/// Returns true iff this is a sticky poll for a workflow task
|
|
443
|
-
fn is_sticky(&self) -> bool;
|
|
444
|
-
|
|
445
|
-
/// Returns the metrics meter if metrics are enabled
|
|
446
|
-
fn get_metrics_meter(&self) -> Option<TemporalMeter> {
|
|
447
|
-
None
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
pub trait SlotMarkUsedContext: Send + Sync {
|
|
452
|
-
type SlotKind: SlotKind;
|
|
453
|
-
/// The slot permit that is being used
|
|
454
|
-
fn permit(&self) -> &SlotSupplierPermit;
|
|
455
|
-
/// Returns the info of slot that was marked as used
|
|
456
|
-
fn info(&self) -> &<Self::SlotKind as SlotKind>::Info;
|
|
457
|
-
|
|
458
|
-
/// Returns the metrics meter if metrics are enabled
|
|
459
|
-
fn get_metrics_meter(&self) -> Option<TemporalMeter> {
|
|
460
|
-
None
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
pub trait SlotReleaseContext: Send + Sync {
|
|
465
|
-
type SlotKind: SlotKind;
|
|
466
|
-
/// The slot permit that is being used
|
|
467
|
-
fn permit(&self) -> &SlotSupplierPermit;
|
|
468
|
-
/// Returns the info of slot that was released, if it was used
|
|
469
|
-
fn info(&self) -> Option<&<Self::SlotKind as SlotKind>::Info>;
|
|
470
|
-
|
|
471
|
-
/// Returns the metrics meter if metrics are enabled
|
|
472
|
-
fn get_metrics_meter(&self) -> Option<TemporalMeter> {
|
|
473
|
-
None
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
#[derive(Default, Debug)]
|
|
478
|
-
pub struct SlotSupplierPermit {
|
|
479
|
-
user_data: Option<Box<dyn Any + Send + Sync>>,
|
|
480
|
-
}
|
|
481
|
-
impl SlotSupplierPermit {
|
|
482
|
-
pub fn with_user_data<T: Any + Send + Sync>(user_data: T) -> Self {
|
|
483
|
-
Self {
|
|
484
|
-
user_data: Some(Box::new(user_data)),
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
/// Attempts to downcast the inner data, if any, into the provided type and returns it.
|
|
488
|
-
/// Returns none if there is no data or the data is not of the appropriate type.
|
|
489
|
-
pub fn user_data<T: Any + Send + Sync>(&self) -> Option<&T> {
|
|
490
|
-
self.user_data.as_ref().and_then(|b| b.downcast_ref())
|
|
491
|
-
}
|
|
492
|
-
/// Attempts to downcast the inner data, if any, into the provided type and returns it mutably.
|
|
493
|
-
/// Returns none if there is no data or the data is not of the appropriate type.
|
|
494
|
-
pub fn user_data_mut<T: Any + Send + Sync>(&mut self) -> Option<&mut T> {
|
|
495
|
-
self.user_data.as_mut().and_then(|b| b.downcast_mut())
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
#[derive(Debug, Copy, Clone, derive_more::Display, Eq, PartialEq)]
|
|
500
|
-
pub enum SlotKindType {
|
|
501
|
-
Workflow,
|
|
502
|
-
Activity,
|
|
503
|
-
LocalActivity,
|
|
504
|
-
Nexus,
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
#[derive(Debug, Copy, Clone)]
|
|
508
|
-
pub struct WorkflowSlotKind {}
|
|
509
|
-
#[derive(Debug, Copy, Clone)]
|
|
510
|
-
pub struct ActivitySlotKind {}
|
|
511
|
-
#[derive(Debug, Copy, Clone)]
|
|
512
|
-
pub struct LocalActivitySlotKind {}
|
|
513
|
-
#[derive(Debug, Copy, Clone)]
|
|
514
|
-
pub struct NexusSlotKind {}
|
|
515
|
-
|
|
516
|
-
pub enum SlotInfo<'a> {
|
|
517
|
-
Workflow(&'a WorkflowSlotInfo),
|
|
518
|
-
Activity(&'a ActivitySlotInfo),
|
|
519
|
-
LocalActivity(&'a LocalActivitySlotInfo),
|
|
520
|
-
Nexus(&'a NexusSlotInfo),
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
pub trait SlotInfoTrait: prost::Message {
|
|
524
|
-
fn downcast(&self) -> SlotInfo<'_>;
|
|
525
|
-
}
|
|
526
|
-
impl SlotInfoTrait for WorkflowSlotInfo {
|
|
527
|
-
fn downcast(&self) -> SlotInfo<'_> {
|
|
528
|
-
SlotInfo::Workflow(self)
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
impl SlotInfoTrait for ActivitySlotInfo {
|
|
532
|
-
fn downcast(&self) -> SlotInfo<'_> {
|
|
533
|
-
SlotInfo::Activity(self)
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
impl SlotInfoTrait for LocalActivitySlotInfo {
|
|
537
|
-
fn downcast(&self) -> SlotInfo<'_> {
|
|
538
|
-
SlotInfo::LocalActivity(self)
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
impl SlotInfoTrait for NexusSlotInfo {
|
|
542
|
-
fn downcast(&self) -> SlotInfo<'_> {
|
|
543
|
-
SlotInfo::Nexus(self)
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
pub trait SlotKind {
|
|
548
|
-
type Info: SlotInfoTrait;
|
|
549
|
-
|
|
550
|
-
fn kind() -> SlotKindType;
|
|
551
|
-
}
|
|
552
|
-
impl SlotKind for WorkflowSlotKind {
|
|
553
|
-
type Info = WorkflowSlotInfo;
|
|
554
|
-
|
|
555
|
-
fn kind() -> SlotKindType {
|
|
556
|
-
SlotKindType::Workflow
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
impl SlotKind for ActivitySlotKind {
|
|
560
|
-
type Info = ActivitySlotInfo;
|
|
561
|
-
|
|
562
|
-
fn kind() -> SlotKindType {
|
|
563
|
-
SlotKindType::Activity
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
impl SlotKind for LocalActivitySlotKind {
|
|
567
|
-
type Info = LocalActivitySlotInfo;
|
|
568
|
-
|
|
569
|
-
fn kind() -> SlotKindType {
|
|
570
|
-
SlotKindType::LocalActivity
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
impl SlotKind for NexusSlotKind {
|
|
574
|
-
type Info = NexusSlotInfo;
|
|
575
|
-
|
|
576
|
-
fn kind() -> SlotKindType {
|
|
577
|
-
SlotKindType::Nexus
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
/// Different strategies for task polling
|
|
582
|
-
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
583
|
-
pub enum PollerBehavior {
|
|
584
|
-
/// Will attempt to poll as long as a slot is available, up to the provided maximum. Cannot
|
|
585
|
-
/// be less than two for workflow tasks, or one for other tasks.
|
|
586
|
-
SimpleMaximum(usize),
|
|
587
|
-
/// Will automatically scale the number of pollers based on feedback from the server. Still
|
|
588
|
-
/// requires a slot to be available before beginning polling.
|
|
589
|
-
Autoscaling {
|
|
590
|
-
/// At least this many poll calls will always be attempted (assuming slots are available).
|
|
591
|
-
/// Cannot be zero.
|
|
592
|
-
minimum: usize,
|
|
593
|
-
/// At most this many poll calls will ever be open at once. Must be >= `minimum`.
|
|
594
|
-
maximum: usize,
|
|
595
|
-
/// This many polls will be attempted initially before scaling kicks in. Must be between
|
|
596
|
-
/// `minimum` and `maximum`.
|
|
597
|
-
initial: usize,
|
|
598
|
-
},
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
impl PollerBehavior {
|
|
602
|
-
/// Returns true if the behavior is using autoscaling
|
|
603
|
-
pub fn is_autoscaling(&self) -> bool {
|
|
604
|
-
matches!(self, PollerBehavior::Autoscaling { .. })
|
|
605
|
-
}
|
|
606
86
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
PollerBehavior::Autoscaling {
|
|
615
|
-
minimum,
|
|
616
|
-
maximum,
|
|
617
|
-
initial,
|
|
618
|
-
} => {
|
|
619
|
-
if *minimum < 1 {
|
|
620
|
-
return Err("Autoscaling minimum poller behavior must be at least 1".to_owned());
|
|
621
|
-
}
|
|
622
|
-
if *maximum < *minimum {
|
|
623
|
-
return Err(
|
|
624
|
-
"Autoscaling maximum must be greater than or equal to minimum".to_owned(),
|
|
625
|
-
);
|
|
626
|
-
}
|
|
627
|
-
if *initial < *minimum || *initial > *maximum {
|
|
628
|
-
return Err(
|
|
629
|
-
"Autoscaling initial must be between minimum and maximum".to_owned()
|
|
630
|
-
);
|
|
631
|
-
}
|
|
632
|
-
}
|
|
87
|
+
/// Converts the enabled task types into the corresponding [`TaskQueueType`] values.
|
|
88
|
+
pub fn to_task_queue_types(&self) -> Vec<TaskQueueType> {
|
|
89
|
+
let mut types = Vec::new();
|
|
90
|
+
if self.enable_workflows {
|
|
91
|
+
types.push(TaskQueueType::Workflow);
|
|
633
92
|
}
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
#[derive(Clone, Debug)]
|
|
639
|
-
pub enum WorkerVersioningStrategy {
|
|
640
|
-
/// Don't enable any versioning
|
|
641
|
-
None {
|
|
642
|
-
/// Build ID may still be passed as a way to identify the worker, or may be left empty.
|
|
643
|
-
build_id: String,
|
|
644
|
-
},
|
|
645
|
-
/// Maybe use the modern deployment-based versioning, or just pass a deployment version.
|
|
646
|
-
WorkerDeploymentBased(WorkerDeploymentOptions),
|
|
647
|
-
/// Use the legacy build-id-based whole worker versioning.
|
|
648
|
-
LegacyBuildIdBased {
|
|
649
|
-
/// A Build ID to use, must be non-empty.
|
|
650
|
-
build_id: String,
|
|
651
|
-
},
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
impl Default for WorkerVersioningStrategy {
|
|
655
|
-
fn default() -> Self {
|
|
656
|
-
WorkerVersioningStrategy::None {
|
|
657
|
-
build_id: String::new(),
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
impl WorkerVersioningStrategy {
|
|
663
|
-
pub fn build_id(&self) -> &str {
|
|
664
|
-
match self {
|
|
665
|
-
WorkerVersioningStrategy::None { build_id } => build_id,
|
|
666
|
-
WorkerVersioningStrategy::WorkerDeploymentBased(opts) => &opts.version.build_id,
|
|
667
|
-
WorkerVersioningStrategy::LegacyBuildIdBased { build_id } => build_id,
|
|
93
|
+
if self.enable_remote_activities {
|
|
94
|
+
types.push(TaskQueueType::Activity);
|
|
668
95
|
}
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
pub fn uses_build_id_based(&self) -> bool {
|
|
672
|
-
matches!(self, WorkerVersioningStrategy::LegacyBuildIdBased { .. })
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
pub fn default_versioning_behavior(&self) -> Option<VersioningBehavior> {
|
|
676
|
-
match self {
|
|
677
|
-
WorkerVersioningStrategy::WorkerDeploymentBased(opts) => {
|
|
678
|
-
opts.default_versioning_behavior
|
|
679
|
-
}
|
|
680
|
-
_ => None,
|
|
96
|
+
if self.enable_nexus {
|
|
97
|
+
types.push(TaskQueueType::Nexus);
|
|
681
98
|
}
|
|
99
|
+
types
|
|
682
100
|
}
|
|
683
101
|
}
|
|
684
102
|
|
|
103
|
+
/// Configuration for worker deployment versioning.
|
|
685
104
|
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
|
686
105
|
pub struct WorkerDeploymentOptions {
|
|
687
106
|
/// The deployment version of this worker.
|
|
@@ -694,6 +113,21 @@ pub struct WorkerDeploymentOptions {
|
|
|
694
113
|
pub default_versioning_behavior: Option<VersioningBehavior>,
|
|
695
114
|
}
|
|
696
115
|
|
|
116
|
+
impl WorkerDeploymentOptions {
|
|
117
|
+
/// Create deployment options from just a build ID, without opting into worker versioning.
|
|
118
|
+
pub fn from_build_id(build_id: String) -> Self {
|
|
119
|
+
Self {
|
|
120
|
+
version: WorkerDeploymentVersion {
|
|
121
|
+
deployment_name: "".to_owned(),
|
|
122
|
+
build_id,
|
|
123
|
+
},
|
|
124
|
+
use_worker_versioning: false,
|
|
125
|
+
default_versioning_behavior: None,
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/// Identifies a specific version of a worker deployment.
|
|
697
131
|
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
|
698
132
|
pub struct WorkerDeploymentVersion {
|
|
699
133
|
/// Name of the deployment
|
|
@@ -703,6 +137,7 @@ pub struct WorkerDeploymentVersion {
|
|
|
703
137
|
}
|
|
704
138
|
|
|
705
139
|
impl WorkerDeploymentVersion {
|
|
140
|
+
/// Returns true if both the deployment name and build ID are empty.
|
|
706
141
|
pub fn is_empty(&self) -> bool {
|
|
707
142
|
self.deployment_name.is_empty() && self.build_id.is_empty()
|
|
708
143
|
}
|
|
@@ -748,3 +183,33 @@ impl From<temporal::api::deployment::v1::WorkerDeploymentVersion> for WorkerDepl
|
|
|
748
183
|
}
|
|
749
184
|
}
|
|
750
185
|
}
|
|
186
|
+
|
|
187
|
+
static CACHED_BUILD_ID: OnceLock<String> = OnceLock::new();
|
|
188
|
+
|
|
189
|
+
/// Build ID derived from hashing the on-disk bytes of the current executable.
|
|
190
|
+
/// Deterministic across machines for the same binary. Cached per-process.
|
|
191
|
+
pub fn build_id_from_current_exe() -> &'static str {
|
|
192
|
+
CACHED_BUILD_ID
|
|
193
|
+
.get_or_init(|| compute_crc32_exe_id().unwrap_or_else(|_| "undetermined".to_owned()))
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
fn compute_crc32_exe_id() -> io::Result<String> {
|
|
197
|
+
let exe_path = std::env::current_exe()?;
|
|
198
|
+
let file = File::open(exe_path)?;
|
|
199
|
+
let mut reader = BufReader::new(file);
|
|
200
|
+
|
|
201
|
+
let mut hasher = crc32fast::Hasher::new();
|
|
202
|
+
let mut buf = [0u8; 128 * 1024];
|
|
203
|
+
|
|
204
|
+
loop {
|
|
205
|
+
let n = reader.read(&mut buf)?;
|
|
206
|
+
if n == 0 {
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
hasher.update(&buf[..n]);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
let crc = hasher.finalize();
|
|
213
|
+
|
|
214
|
+
Ok(format!("{:08x}", crc))
|
|
215
|
+
}
|