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