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