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