@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,28 +1,27 @@
1
- use crate::{
2
- common::{
3
- ActivationAssertionsInterceptor, CoreWfStarter, INTEG_CLIENT_IDENTITY, build_fake_sdk,
4
- eventually, init_core_and_create_wf, mock_sdk, mock_sdk_cfg,
5
- },
6
- integ_tests::activity_functions::echo,
1
+ use crate::common::{
2
+ ActivationAssertionsInterceptor, CoreWfStarter, INTEG_CLIENT_IDENTITY,
3
+ activity_functions::StdActivities, build_fake_sdk, eventually, init_core_and_create_wf,
4
+ mock_sdk, mock_sdk_cfg,
7
5
  };
8
6
  use anyhow::anyhow;
9
7
  use assert_matches::assert_matches;
10
- use futures_util::future::join_all;
11
8
  use std::{
12
- sync::atomic::{AtomicBool, Ordering},
9
+ sync::{
10
+ Arc,
11
+ atomic::{AtomicBool, Ordering},
12
+ },
13
13
  time::Duration,
14
14
  };
15
15
  use temporalio_client::{
16
- WfClientExt, WorkflowClientTrait, WorkflowExecutionResult, WorkflowOptions,
16
+ ActivityIdentifier, UntypedWorkflow, WorkflowDescribeOptions, WorkflowStartOptions,
17
+ WorkflowTerminateOptions,
17
18
  };
18
19
  use temporalio_common::{
19
20
  prost_dur,
20
21
  protos::{
21
- DEFAULT_ACTIVITY_TYPE, DEFAULT_WORKFLOW_TYPE, TaskToken, TestHistoryBuilder,
22
- canned_histories,
22
+ DEFAULT_ACTIVITY_TYPE, DEFAULT_WORKFLOW_TYPE, TestHistoryBuilder, canned_histories,
23
23
  coresdk::{
24
- ActivityHeartbeat, ActivityTaskCompletion, AsJsonPayloadExt, FromJsonPayloadExt,
25
- IntoCompletion, IntoPayloadsExt,
24
+ ActivityHeartbeat, ActivityTaskCompletion, IntoCompletion, IntoPayloadsExt,
26
25
  activity_result::{
27
26
  self, ActivityExecutionResult, ActivityResolution, activity_resolution as act_res,
28
27
  },
@@ -43,53 +42,115 @@ use temporalio_common::{
43
42
  },
44
43
  test_utils::schedule_activity_cmd,
45
44
  },
46
- worker::PollerBehavior,
47
45
  };
46
+ use temporalio_macros::{activities, workflow, workflow_methods};
48
47
  use temporalio_sdk::{
49
- ActContext, ActExitValue, ActivityError, ActivityOptions, CancellableFuture, WfContext,
50
- WfExitValue, WorkflowFunction, WorkflowResult,
48
+ ActivityOptions, CancellableFuture, WorkflowContext, WorkflowResult, WorkflowTermination,
49
+ activities::{ActivityContext, ActivityError},
51
50
  };
52
- use temporalio_sdk_core::test_help::{
53
- MockPollCfg, ResponseType, WorkerTestHelpers, drain_pollers_and_shutdown, mock_worker_client,
51
+ use temporalio_sdk_core::{
52
+ PollerBehavior,
53
+ test_help::{
54
+ MockPollCfg, ResponseType, WorkerTestHelpers, drain_pollers_and_shutdown,
55
+ mock_worker_client,
56
+ },
54
57
  };
55
58
  use tokio::{join, sync::Semaphore, time::sleep};
56
59
 
57
- pub(crate) async fn one_activity_wf(ctx: WfContext) -> WorkflowResult<()> {
58
- ctx.activity(ActivityOptions {
59
- activity_type: "echo_activity".to_string(),
60
- start_to_close_timeout: Some(Duration::from_secs(5)),
61
- input: "hi!".as_json_payload().expect("serializes fine"),
62
- ..Default::default()
63
- })
64
- .await;
65
- Ok(().into())
60
+ #[workflow]
61
+ #[derive(Default)]
62
+ struct OneActivityWorkflow;
63
+
64
+ #[workflow_methods]
65
+ impl OneActivityWorkflow {
66
+ #[run]
67
+ async fn run(ctx: &mut WorkflowContext<Self>, input: String) -> WorkflowResult<String> {
68
+ let r = ctx
69
+ .start_activity(
70
+ StdActivities::echo,
71
+ input,
72
+ ActivityOptions {
73
+ start_to_close_timeout: Some(Duration::from_secs(5)),
74
+ ..Default::default()
75
+ },
76
+ )
77
+ .await
78
+ .map_err(|e| anyhow!("{e}"))?;
79
+ Ok(r)
80
+ }
81
+ }
82
+
83
+ #[workflow]
84
+ #[derive(Default)]
85
+ struct MultiArgActivityWorkflow;
86
+
87
+ #[workflow_methods]
88
+ impl MultiArgActivityWorkflow {
89
+ #[run]
90
+ async fn run(ctx: &mut WorkflowContext<Self>, input: String) -> WorkflowResult<String> {
91
+ let r = ctx
92
+ .start_activity(
93
+ StdActivities::concat,
94
+ (input, " world".to_string()),
95
+ ActivityOptions {
96
+ start_to_close_timeout: Some(Duration::from_secs(5)),
97
+ ..Default::default()
98
+ },
99
+ )
100
+ .await
101
+ .map_err(|e| anyhow!("{e}"))?;
102
+ Ok(r)
103
+ }
66
104
  }
67
105
 
68
106
  #[tokio::test]
69
- async fn one_activity_only() {
70
- let wf_name = "one_activity";
107
+ async fn multi_arg_activity() {
108
+ let wf_name = MultiArgActivityWorkflow::name();
71
109
  let mut starter = CoreWfStarter::new(wf_name);
110
+ starter.sdk_config.register_activities(StdActivities);
111
+ starter
112
+ .sdk_config
113
+ .register_workflow::<MultiArgActivityWorkflow>();
72
114
  let mut worker = starter.worker().await;
73
- let client = starter.get_client().await;
74
- worker.register_wf(wf_name.to_owned(), one_activity_wf);
75
- worker.register_activity("echo_activity", echo);
76
115
 
77
- let run_id = worker
78
- .submit_wf(
79
- wf_name.to_owned(),
80
- wf_name.to_owned(),
81
- vec![],
82
- WorkflowOptions::default(),
116
+ let input = "hello".to_string();
117
+ let task_queue = starter.get_task_queue().to_owned();
118
+ let handle = worker
119
+ .submit_workflow(
120
+ MultiArgActivityWorkflow::run,
121
+ input,
122
+ WorkflowStartOptions::new(task_queue, wf_name.to_owned()).build(),
83
123
  )
84
124
  .await
85
125
  .unwrap();
86
126
  worker.run_until_done().await.unwrap();
87
- let handle = client.get_untyped_workflow_handle(wf_name, run_id);
88
- let res = handle
89
- .get_workflow_result(Default::default())
127
+ let r = handle.get_result(Default::default()).await.unwrap();
128
+ assert_eq!(r, "hello world");
129
+ }
130
+
131
+ #[tokio::test]
132
+ async fn one_activity_only() {
133
+ let wf_name = OneActivityWorkflow::name();
134
+ let mut starter = CoreWfStarter::new(wf_name);
135
+ starter.sdk_config.register_activities(StdActivities);
136
+ starter
137
+ .sdk_config
138
+ .register_workflow::<OneActivityWorkflow>();
139
+ let mut worker = starter.worker().await;
140
+
141
+ let input = "hello from input!".to_string();
142
+ let task_queue = starter.get_task_queue().to_owned();
143
+ let handle = worker
144
+ .submit_workflow(
145
+ OneActivityWorkflow::run,
146
+ input.clone(),
147
+ WorkflowStartOptions::new(task_queue, wf_name.to_owned()).build(),
148
+ )
90
149
  .await
91
150
  .unwrap();
92
- assert_matches!(res, WorkflowExecutionResult::Succeeded(_));
151
+ worker.run_until_done().await.unwrap();
152
+ let r = handle.get_result(Default::default()).await.unwrap();
153
+ assert_eq!(r, input);
93
154
  }
94
155
 
95
156
  #[tokio::test]
@@ -124,6 +185,7 @@ async fn activity_workflow() {
124
185
  let response_payload = Payload {
125
186
  data: b"hello ".to_vec(),
126
187
  metadata: Default::default(),
188
+ external_payloads: Default::default(),
127
189
  };
128
190
  // Complete activity successfully.
129
191
  core.complete_activity_task(ActivityTaskCompletion {
@@ -327,6 +389,7 @@ async fn activity_retry() {
327
389
  let response_payload = Payload {
328
390
  data: b"hello ".to_vec(),
329
391
  metadata: Default::default(),
392
+ external_payloads: Default::default(),
330
393
  };
331
394
  core.complete_activity_task(ActivityTaskCompletion {
332
395
  task_token: task.task_token,
@@ -701,6 +764,7 @@ async fn async_activity_completion_workflow() {
701
764
  let response_payload = Payload {
702
765
  data: b"hello ".to_vec(),
703
766
  metadata: Default::default(),
767
+ external_payloads: Default::default(),
704
768
  };
705
769
  // Complete activity asynchronously.
706
770
  core.complete_activity_task(ActivityTaskCompletion {
@@ -712,12 +776,10 @@ async fn async_activity_completion_workflow() {
712
776
  starter
713
777
  .get_client()
714
778
  .await
715
- .complete_activity_task(
716
- task.task_token.into(),
717
- Some(Payloads {
718
- payloads: vec![response_payload.clone()],
719
- }),
720
- )
779
+ .get_async_activity_handle(ActivityIdentifier::TaskToken(task.task_token.into()))
780
+ .complete(Some(Payloads {
781
+ payloads: vec![response_payload.clone()],
782
+ }))
721
783
  .await
722
784
  .unwrap();
723
785
 
@@ -798,7 +860,8 @@ async fn activity_cancelled_after_heartbeat_times_out() {
798
860
  starter
799
861
  .get_client()
800
862
  .await
801
- .terminate_workflow_execution(task_q, None)
863
+ .get_workflow_handle::<UntypedWorkflow>(task_q)
864
+ .terminate(WorkflowTerminateOptions::default())
802
865
  .await
803
866
  .unwrap();
804
867
  }
@@ -858,10 +921,12 @@ async fn activity_heartbeat_not_flushed_on_success() {
858
921
  || async {
859
922
  // Verify pending details has the flushed heartbeat
860
923
  let details = client
861
- .describe_workflow_execution(starter.get_wf_id().to_string(), None)
924
+ .get_workflow_handle::<UntypedWorkflow>(starter.get_wf_id().to_string())
925
+ .describe(WorkflowDescribeOptions::default())
862
926
  .await
863
927
  .unwrap();
864
928
  let last_deets = details
929
+ .raw_description
865
930
  .pending_activities
866
931
  .into_iter()
867
932
  .find(|i| i.activity_id == activity_id)
@@ -877,224 +942,179 @@ async fn activity_heartbeat_not_flushed_on_success() {
877
942
  .await
878
943
  .unwrap();
879
944
  client
880
- .terminate_workflow_execution(task_q, None)
945
+ .get_workflow_handle::<UntypedWorkflow>(task_q)
946
+ .terminate(WorkflowTerminateOptions::default())
881
947
  .await
882
948
  .unwrap();
883
949
  drain_pollers_and_shutdown(&core).await;
884
950
  }
885
951
 
952
+ #[workflow]
953
+ #[derive(Default)]
954
+ struct OneActivityAbandonCancelledBeforeStarted;
955
+
956
+ #[workflow_methods]
957
+ impl OneActivityAbandonCancelledBeforeStarted {
958
+ #[run]
959
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
960
+ let act_fut = ctx.start_activity(
961
+ StdActivities::delay,
962
+ Duration::from_secs(2),
963
+ ActivityOptions {
964
+ start_to_close_timeout: Some(Duration::from_secs(5)),
965
+ cancellation_type: ActivityCancellationType::Abandon,
966
+ ..Default::default()
967
+ },
968
+ );
969
+ act_fut.cancel();
970
+ let _ = act_fut.await;
971
+ Ok(())
972
+ }
973
+ }
974
+
886
975
  #[tokio::test]
887
976
  async fn one_activity_abandon_cancelled_before_started() {
888
977
  let wf_name = "one_activity_abandon_cancelled_before_started";
889
978
  let mut starter = CoreWfStarter::new(wf_name);
979
+ starter.sdk_config.register_activities(StdActivities);
980
+ starter
981
+ .sdk_config
982
+ .register_workflow::<OneActivityAbandonCancelledBeforeStarted>();
890
983
  let mut worker = starter.worker().await;
891
- let client = starter.get_client().await;
892
- worker.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
893
- let act_fut = ctx.activity(ActivityOptions {
894
- activity_type: "echo_activity".to_string(),
895
- start_to_close_timeout: Some(Duration::from_secs(5)),
896
- input: "hi!".as_json_payload().expect("serializes fine"),
897
- cancellation_type: ActivityCancellationType::Abandon,
898
- ..Default::default()
899
- });
900
- act_fut.cancel(&ctx);
901
- act_fut.await;
902
- Ok(().into())
903
- });
904
- worker.register_activity(
905
- "echo_activity",
906
- |_ctx: ActContext, echo_me: String| async move {
907
- sleep(Duration::from_secs(2)).await;
908
- Ok(echo_me)
909
- },
910
- );
911
984
 
912
- let run_id = worker
913
- .submit_wf(
914
- wf_name.to_owned(),
915
- wf_name.to_owned(),
916
- vec![],
917
- WorkflowOptions::default(),
985
+ let task_queue = starter.get_task_queue().to_owned();
986
+ let handle = worker
987
+ .submit_workflow(
988
+ OneActivityAbandonCancelledBeforeStarted::run,
989
+ (),
990
+ WorkflowStartOptions::new(task_queue, wf_name).build(),
918
991
  )
919
992
  .await
920
993
  .unwrap();
921
994
  worker.run_until_done().await.unwrap();
922
- let handle = client.get_untyped_workflow_handle(wf_name, run_id);
923
- let res = handle
924
- .get_workflow_result(Default::default())
925
- .await
926
- .unwrap();
927
- assert_matches!(res, WorkflowExecutionResult::Succeeded(_));
995
+ handle.get_result(Default::default()).await.unwrap();
996
+ }
997
+
998
+ #[workflow]
999
+ #[derive(Default)]
1000
+ struct OneActivityAbandonCancelledAfterComplete;
1001
+
1002
+ #[workflow_methods]
1003
+ impl OneActivityAbandonCancelledAfterComplete {
1004
+ #[run]
1005
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
1006
+ let act_fut = ctx.start_activity(
1007
+ StdActivities::delay,
1008
+ Duration::from_secs(2),
1009
+ ActivityOptions {
1010
+ start_to_close_timeout: Some(Duration::from_secs(5)),
1011
+ cancellation_type: ActivityCancellationType::Abandon,
1012
+ ..Default::default()
1013
+ },
1014
+ );
1015
+ ctx.timer(Duration::from_secs(1)).await;
1016
+ act_fut.cancel();
1017
+ ctx.timer(Duration::from_secs(3)).await;
1018
+ let _ = act_fut.await;
1019
+ Ok(())
1020
+ }
928
1021
  }
929
1022
 
930
1023
  #[tokio::test]
931
1024
  async fn one_activity_abandon_cancelled_after_complete() {
932
1025
  let wf_name = "one_activity_abandon_cancelled_after_complete";
933
1026
  let mut starter = CoreWfStarter::new(wf_name);
1027
+ starter.sdk_config.register_activities(StdActivities);
1028
+ starter
1029
+ .sdk_config
1030
+ .register_workflow::<OneActivityAbandonCancelledAfterComplete>();
934
1031
  let mut worker = starter.worker().await;
935
- let client = starter.get_client().await;
936
- worker.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
937
- let act_fut = ctx.activity(ActivityOptions {
938
- activity_type: "echo_activity".to_string(),
939
- start_to_close_timeout: Some(Duration::from_secs(5)),
940
- input: "hi!".as_json_payload().expect("serializes fine"),
941
- cancellation_type: ActivityCancellationType::Abandon,
942
- ..Default::default()
943
- });
944
- ctx.timer(Duration::from_secs(1)).await;
945
- act_fut.cancel(&ctx);
946
- ctx.timer(Duration::from_secs(3)).await;
947
- act_fut.await;
948
- Ok(().into())
949
- });
950
- worker.register_activity(
951
- "echo_activity",
952
- |_ctx: ActContext, echo_me: String| async move {
953
- sleep(Duration::from_secs(2)).await;
954
- Ok(echo_me)
955
- },
956
- );
957
1032
 
958
- let run_id = worker
959
- .submit_wf(
960
- wf_name.to_owned(),
961
- wf_name.to_owned(),
962
- vec![],
963
- WorkflowOptions::default(),
1033
+ let task_queue = starter.get_task_queue().to_owned();
1034
+ let handle = worker
1035
+ .submit_workflow(
1036
+ OneActivityAbandonCancelledAfterComplete::run,
1037
+ (),
1038
+ WorkflowStartOptions::new(task_queue, wf_name).build(),
964
1039
  )
965
1040
  .await
966
1041
  .unwrap();
967
1042
  worker.run_until_done().await.unwrap();
968
- let handle = client.get_untyped_workflow_handle(wf_name, run_id);
969
- let res = handle
970
- .get_workflow_result(Default::default())
971
- .await
972
- .unwrap();
973
- assert_matches!(res, WorkflowExecutionResult::Succeeded(_));
1043
+ handle.get_result(Default::default()).await.unwrap();
974
1044
  }
975
1045
 
976
1046
  #[tokio::test]
977
- async fn it_can_complete_async() {
978
- use std::sync::Arc;
979
- use tokio::sync::Mutex;
1047
+ async fn graceful_shutdown() {
1048
+ let wf_name = "graceful_shutdown";
1049
+ let mut starter = CoreWfStarter::new(wf_name);
1050
+ starter.sdk_config.graceful_shutdown_period = Some(Duration::from_millis(500));
980
1051
 
981
- let wf_name = "it_can_complete_async".to_owned();
982
- let mut starter = CoreWfStarter::new(&wf_name);
983
- let mut worker = starter.worker().await;
984
- let client = starter.get_client().await;
985
- let async_response = "agence";
986
- let shared_token: Arc<Mutex<Option<Vec<u8>>>> = Arc::new(Mutex::new(None));
987
- worker.register_wf(wf_name.clone(), move |ctx: WfContext| async move {
988
- let activity_resolution = ctx
989
- .activity(ActivityOptions {
990
- activity_type: "complete_async_activity".to_string(),
991
- input: "hi".as_json_payload().expect("serializes fine"),
992
- start_to_close_timeout: Some(Duration::from_secs(30)),
993
- ..Default::default()
994
- })
995
- .await;
1052
+ let acts_started = Arc::new(Semaphore::const_new(0));
1053
+ let acts_done = Arc::new(Semaphore::const_new(0));
996
1054
 
997
- let res = match activity_resolution.status {
998
- Some(act_res::Status::Completed(activity_result::Success { result })) => result
999
- .map(|p| String::from_json_payload(&p).unwrap())
1000
- .unwrap(),
1001
- _ => panic!("activity task failed {activity_resolution:?}"),
1002
- };
1055
+ struct SleeperActivities {
1056
+ acts_started: Arc<Semaphore>,
1057
+ acts_done: Arc<Semaphore>,
1058
+ }
1059
+ #[activities]
1060
+ impl SleeperActivities {
1061
+ #[activity]
1062
+ async fn sleeper(
1063
+ self: Arc<Self>,
1064
+ ctx: ActivityContext,
1065
+ _: String,
1066
+ ) -> Result<(), ActivityError> {
1067
+ self.acts_started.add_permits(1);
1068
+ // just wait to be cancelled
1069
+ ctx.cancelled().await;
1070
+ self.acts_done.add_permits(1);
1071
+ Err(ActivityError::cancelled())
1072
+ }
1073
+ }
1003
1074
 
1004
- assert_eq!(&res, async_response);
1005
- Ok(().into())
1075
+ starter.sdk_config.register_activities(SleeperActivities {
1076
+ acts_started: acts_started.clone(),
1077
+ acts_done: acts_done.clone(),
1006
1078
  });
1079
+ let mut worker = starter.worker().await;
1080
+ let client = starter.get_client().await;
1007
1081
 
1008
- let shared_token_ref = shared_token.clone();
1009
- worker.register_activity(
1010
- "complete_async_activity",
1011
- move |ctx: ActContext, _: String| {
1012
- let shared_token_ref = shared_token_ref.clone();
1013
- async move {
1014
- // set the `activity_task_token`
1015
- let activity_info = ctx.get_info();
1016
- let task_token = &activity_info.task_token;
1017
- let mut shared = shared_token_ref.lock().await;
1018
- *shared = Some(task_token.clone());
1019
- Ok::<ActExitValue<()>, _>(ActExitValue::WillCompleteAsync)
1020
- }
1021
- },
1022
- );
1082
+ #[workflow]
1083
+ #[derive(Default)]
1084
+ struct GracefulShutdownWorkflow;
1023
1085
 
1024
- let shared_token_ref2 = shared_token.clone();
1025
- tokio::spawn(async move {
1026
- loop {
1027
- let mut shared = shared_token_ref2.lock().await;
1028
- let maybe_token = shared.take();
1029
-
1030
- if let Some(task_token) = maybe_token {
1031
- client
1032
- .complete_activity_task(
1033
- TaskToken(task_token),
1034
- Some(async_response.as_json_payload().unwrap().into()),
1035
- )
1036
- .await
1037
- .unwrap();
1038
- return;
1039
- }
1086
+ #[workflow_methods]
1087
+ impl GracefulShutdownWorkflow {
1088
+ #[run]
1089
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
1090
+ let act_futs = (1..=10).map(|_| {
1091
+ ctx.start_activity(
1092
+ SleeperActivities::sleeper,
1093
+ "hi".to_string(),
1094
+ ActivityOptions {
1095
+ start_to_close_timeout: Some(Duration::from_secs(5)),
1096
+ retry_policy: Some(RetryPolicy {
1097
+ maximum_attempts: 1,
1098
+ ..Default::default()
1099
+ }),
1100
+ cancellation_type: ActivityCancellationType::WaitCancellationCompleted,
1101
+ ..Default::default()
1102
+ },
1103
+ )
1104
+ });
1105
+ temporalio_sdk::workflows::join_all(act_futs).await;
1106
+ Ok(())
1040
1107
  }
1041
- });
1108
+ }
1042
1109
 
1043
- let _run_id = worker
1044
- .submit_wf(
1045
- wf_name.to_owned(),
1046
- wf_name.to_owned(),
1047
- vec![],
1048
- WorkflowOptions::default(),
1049
- )
1050
- .await
1051
- .unwrap();
1052
-
1053
- worker.run_until_done().await.unwrap();
1054
- }
1055
-
1056
- #[tokio::test]
1057
- async fn graceful_shutdown() {
1058
- let wf_name = "graceful_shutdown";
1059
- let mut starter = CoreWfStarter::new(wf_name);
1060
- starter
1061
- .worker_config
1062
- .graceful_shutdown_period(Some(Duration::from_millis(500)));
1063
- let mut worker = starter.worker().await;
1064
- let client = starter.get_client().await;
1065
- worker.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
1066
- let act_futs = (1..=10).map(|_| {
1067
- ctx.activity(ActivityOptions {
1068
- activity_type: "sleeper".to_string(),
1069
- start_to_close_timeout: Some(Duration::from_secs(5)),
1070
- retry_policy: Some(RetryPolicy {
1071
- maximum_attempts: 1,
1072
- ..Default::default()
1073
- }),
1074
- cancellation_type: ActivityCancellationType::WaitCancellationCompleted,
1075
- input: "hi".as_json_payload().unwrap(),
1076
- ..Default::default()
1077
- })
1078
- });
1079
- join_all(act_futs).await;
1080
- Ok(().into())
1081
- });
1082
- static ACTS_STARTED: Semaphore = Semaphore::const_new(0);
1083
- static ACTS_DONE: Semaphore = Semaphore::const_new(0);
1084
- worker.register_activity("sleeper", |ctx: ActContext, _: String| async move {
1085
- ACTS_STARTED.add_permits(1);
1086
- // just wait to be cancelled
1087
- ctx.cancelled().await;
1088
- ACTS_DONE.add_permits(1);
1089
- Result::<(), _>::Err(ActivityError::cancelled())
1090
- });
1110
+ worker.register_workflow::<GracefulShutdownWorkflow>();
1091
1111
 
1112
+ let task_queue = starter.get_task_queue().to_owned();
1092
1113
  worker
1093
- .submit_wf(
1094
- wf_name.to_owned(),
1095
- wf_name.to_owned(),
1096
- vec![],
1097
- WorkflowOptions::default(),
1114
+ .submit_workflow(
1115
+ GracefulShutdownWorkflow::run,
1116
+ (),
1117
+ WorkflowStartOptions::new(task_queue, wf_name).build(),
1098
1118
  )
1099
1119
  .await
1100
1120
  .unwrap();
@@ -1102,13 +1122,14 @@ async fn graceful_shutdown() {
1102
1122
  let handle = worker.inner_mut().shutdown_handle();
1103
1123
  let shutdowner = async {
1104
1124
  // Wait for all acts to be started before initiating shutdown
1105
- let _ = ACTS_STARTED.acquire_many(10).await;
1125
+ let _ = acts_started.acquire_many(10).await;
1106
1126
  handle();
1107
1127
  // Kill workflow once all acts are cancelled. This also ensures we actually see all the
1108
1128
  // cancels, otherwise run_until_done will hang since the workflow won't complete.
1109
- let _ = ACTS_DONE.acquire_many(10).await;
1129
+ let _ = acts_done.acquire_many(10).await;
1110
1130
  client
1111
- .terminate_workflow_execution(wf_name.to_owned(), None)
1131
+ .get_workflow_handle::<UntypedWorkflow>(wf_name.to_owned())
1132
+ .terminate(WorkflowTerminateOptions::default())
1112
1133
  .await
1113
1134
  .unwrap();
1114
1135
  };
@@ -1123,39 +1144,75 @@ async fn activity_can_be_cancelled_by_local_timeout() {
1123
1144
  let wf_name = "activity_can_be_cancelled_by_local_timeout";
1124
1145
  let mut starter = CoreWfStarter::new(wf_name);
1125
1146
  starter
1126
- .worker_config
1127
- .local_timeout_buffer_for_activities(Duration::from_secs(0));
1128
- let mut worker = starter.worker().await;
1129
- worker.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
1130
- let res = ctx
1131
- .activity(ActivityOptions {
1132
- activity_type: "echo_activity".to_string(),
1133
- start_to_close_timeout: Some(Duration::from_secs(1)),
1134
- input: "hi!".as_json_payload().expect("serializes fine"),
1135
- retry_policy: Some(RetryPolicy {
1136
- maximum_attempts: 1,
1137
- ..Default::default()
1138
- }),
1139
- ..Default::default()
1140
- })
1141
- .await;
1142
- assert!(res.timed_out().is_some());
1143
- Ok(().into())
1144
- });
1145
- static WAS_CANCELLED: AtomicBool = AtomicBool::new(false);
1146
- worker.register_activity(
1147
- "echo_activity",
1148
- |ctx: ActContext, echo_me: String| async move {
1147
+ .set_core_cfg_mutator(|m| m.local_timeout_buffer_for_activities = Duration::from_secs(0));
1148
+
1149
+ let was_cancelled = Arc::new(AtomicBool::new(false));
1150
+
1151
+ struct CancellableEchoActivities {
1152
+ was_cancelled: Arc<AtomicBool>,
1153
+ }
1154
+ #[activities]
1155
+ impl CancellableEchoActivities {
1156
+ #[activity]
1157
+ async fn cancellable_echo(
1158
+ self: Arc<Self>,
1159
+ ctx: ActivityContext,
1160
+ echo_me: String,
1161
+ ) -> Result<String, ActivityError> {
1149
1162
  // Doesn't heartbeat
1150
1163
  ctx.cancelled().await;
1151
- WAS_CANCELLED.store(true, Ordering::Relaxed);
1164
+ self.was_cancelled.store(true, Ordering::Relaxed);
1152
1165
  Ok(echo_me)
1153
- },
1154
- );
1166
+ }
1167
+ }
1155
1168
 
1156
- starter.start_with_worker(wf_name, &mut worker).await;
1169
+ starter
1170
+ .sdk_config
1171
+ .register_activities(CancellableEchoActivities {
1172
+ was_cancelled: was_cancelled.clone(),
1173
+ });
1174
+ let mut worker = starter.worker().await;
1175
+
1176
+ #[workflow]
1177
+ #[derive(Default)]
1178
+ struct ActivityLocalTimeoutWorkflow;
1179
+
1180
+ #[workflow_methods]
1181
+ impl ActivityLocalTimeoutWorkflow {
1182
+ #[run]
1183
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
1184
+ let res = ctx
1185
+ .start_activity(
1186
+ CancellableEchoActivities::cancellable_echo,
1187
+ "hi!".to_string(),
1188
+ ActivityOptions {
1189
+ start_to_close_timeout: Some(Duration::from_secs(1)),
1190
+ retry_policy: Some(RetryPolicy {
1191
+ maximum_attempts: 1,
1192
+ ..Default::default()
1193
+ }),
1194
+ ..Default::default()
1195
+ },
1196
+ )
1197
+ .await;
1198
+ assert!(res.is_err_and(|e| e.is_timeout()));
1199
+ Ok(())
1200
+ }
1201
+ }
1202
+
1203
+ worker.register_workflow::<ActivityLocalTimeoutWorkflow>();
1204
+
1205
+ let task_queue = starter.get_task_queue().to_owned();
1206
+ worker
1207
+ .submit_workflow(
1208
+ ActivityLocalTimeoutWorkflow::run,
1209
+ (),
1210
+ WorkflowStartOptions::new(task_queue.clone(), task_queue).build(),
1211
+ )
1212
+ .await
1213
+ .unwrap();
1157
1214
  worker.run_until_done().await.unwrap();
1158
- assert!(WAS_CANCELLED.load(Ordering::Relaxed));
1215
+ assert!(was_cancelled.load(Ordering::Relaxed));
1159
1216
  }
1160
1217
 
1161
1218
  #[tokio::test]
@@ -1165,44 +1222,56 @@ async fn activity_can_be_cancelled_by_local_timeout() {
1165
1222
  async fn long_activity_timeout_repro() {
1166
1223
  let wf_name = "long_activity_timeout_repro";
1167
1224
  let mut starter = CoreWfStarter::new(wf_name);
1225
+ starter.sdk_config.workflow_task_poller_behavior = PollerBehavior::Autoscaling {
1226
+ minimum: 1,
1227
+ maximum: 10,
1228
+ initial: 5,
1229
+ };
1230
+ starter.sdk_config.activity_task_poller_behavior = PollerBehavior::Autoscaling {
1231
+ minimum: 1,
1232
+ maximum: 10,
1233
+ initial: 5,
1234
+ };
1168
1235
  starter
1169
- .worker_config
1170
- .workflow_task_poller_behavior(PollerBehavior::Autoscaling {
1171
- minimum: 1,
1172
- maximum: 10,
1173
- initial: 5,
1174
- })
1175
- .activity_task_poller_behavior(PollerBehavior::Autoscaling {
1176
- minimum: 1,
1177
- maximum: 10,
1178
- initial: 5,
1179
- })
1180
- .local_timeout_buffer_for_activities(Duration::from_secs(0));
1236
+ .set_core_cfg_mutator(|m| m.local_timeout_buffer_for_activities = Duration::from_secs(0));
1237
+ starter.sdk_config.register_activities(StdActivities);
1181
1238
  let mut worker = starter.worker().await;
1182
- worker.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
1183
- let mut iter = 1;
1184
- loop {
1185
- let res = ctx
1186
- .activity(ActivityOptions {
1187
- activity_type: "echo_activity".to_string(),
1188
- start_to_close_timeout: Some(Duration::from_secs(1)),
1189
- input: "hi!".as_json_payload().expect("serializes fine"),
1190
- retry_policy: Some(RetryPolicy {
1191
- maximum_attempts: 1,
1192
- ..Default::default()
1193
- }),
1194
- ..Default::default()
1195
- })
1196
- .await;
1197
- assert!(res.completed_ok());
1198
- ctx.timer(Duration::from_secs(60 * 3)).await;
1199
- iter += 1;
1200
- if iter > 5000 {
1201
- return Ok(WfExitValue::<()>::continue_as_new(Default::default()));
1239
+
1240
+ #[workflow]
1241
+ #[derive(Default)]
1242
+ struct LongActivityTimeoutReproWorkflow;
1243
+
1244
+ #[workflow_methods]
1245
+ impl LongActivityTimeoutReproWorkflow {
1246
+ #[run]
1247
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
1248
+ let mut iter = 1;
1249
+ loop {
1250
+ let res = ctx
1251
+ .start_activity(
1252
+ StdActivities::echo,
1253
+ "hi!".to_string(),
1254
+ ActivityOptions {
1255
+ start_to_close_timeout: Some(Duration::from_secs(1)),
1256
+ retry_policy: Some(RetryPolicy {
1257
+ maximum_attempts: 1,
1258
+ ..Default::default()
1259
+ }),
1260
+ ..Default::default()
1261
+ },
1262
+ )
1263
+ .await;
1264
+ assert!(res.is_ok());
1265
+ ctx.timer(Duration::from_secs(60 * 3)).await;
1266
+ iter += 1;
1267
+ if iter > 5000 {
1268
+ return Err(WorkflowTermination::continue_as_new(Default::default()));
1269
+ }
1202
1270
  }
1203
1271
  }
1204
- });
1205
- worker.register_activity("echo_activity", echo);
1272
+ }
1273
+
1274
+ worker.register_workflow::<LongActivityTimeoutReproWorkflow>();
1206
1275
 
1207
1276
  starter.start_with_worker(wf_name, &mut worker).await;
1208
1277
  worker.run_until_done().await.unwrap();
@@ -1238,21 +1307,36 @@ async fn pass_activity_summary_to_metadata() {
1238
1307
  });
1239
1308
 
1240
1309
  let mut worker = mock_sdk_cfg(mock_cfg, |_| {});
1241
- worker.register_wf(wf_type, |ctx: WfContext| async move {
1242
- ctx.activity(ActivityOptions {
1243
- activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
1244
- summary: Some("activity summary".to_string()),
1245
- ..Default::default()
1246
- })
1247
- .await;
1248
- Ok(().into())
1249
- });
1310
+
1311
+ #[workflow]
1312
+ #[derive(Default)]
1313
+ struct ActivitySummaryWorkflow;
1314
+
1315
+ #[workflow_methods]
1316
+ impl ActivitySummaryWorkflow {
1317
+ #[run(name = DEFAULT_WORKFLOW_TYPE)]
1318
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
1319
+ ctx.start_activity(
1320
+ StdActivities::default,
1321
+ (),
1322
+ ActivityOptions {
1323
+ summary: Some("activity summary".to_string()),
1324
+ ..Default::default()
1325
+ },
1326
+ )
1327
+ .await
1328
+ .map_err(|e| anyhow!("{e}"))?;
1329
+ Ok(())
1330
+ }
1331
+ }
1332
+
1333
+ worker.register_workflow::<ActivitySummaryWorkflow>();
1334
+ let task_queue = worker.inner_mut().task_queue().to_owned();
1250
1335
  worker
1251
1336
  .submit_wf(
1252
- wf_id.to_owned(),
1253
1337
  wf_type.to_owned(),
1254
1338
  vec![],
1255
- WorkflowOptions::default(),
1339
+ WorkflowStartOptions::new(task_queue, wf_id.to_owned()).build(),
1256
1340
  )
1257
1341
  .await
1258
1342
  .unwrap();
@@ -1287,42 +1371,68 @@ async fn abandoned_activities_ignore_start_and_complete(hist_batches: &'static [
1287
1371
  let mock = mock_worker_client();
1288
1372
  let mut worker = mock_sdk(MockPollCfg::from_resp_batches(wfid, t, hist_batches, mock));
1289
1373
 
1290
- worker.register_wf(wf_type.to_owned(), |ctx: WfContext| async move {
1291
- let act_fut = ctx.activity(ActivityOptions {
1292
- activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
1293
- start_to_close_timeout: Some(Duration::from_secs(5)),
1294
- cancellation_type: ActivityCancellationType::Abandon,
1295
- ..Default::default()
1296
- });
1297
- ctx.timer(Duration::from_secs(1)).await;
1298
- act_fut.cancel(&ctx);
1299
- ctx.timer(Duration::from_secs(3)).await;
1300
- act_fut.await;
1301
- Ok(().into())
1302
- });
1374
+ #[workflow]
1375
+ #[derive(Default)]
1376
+ struct AbandonedActivitiesWorkflow;
1377
+
1378
+ #[workflow_methods]
1379
+ impl AbandonedActivitiesWorkflow {
1380
+ #[run(name = DEFAULT_WORKFLOW_TYPE)]
1381
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
1382
+ let act_fut = ctx.start_activity(
1383
+ StdActivities::default,
1384
+ (),
1385
+ ActivityOptions {
1386
+ start_to_close_timeout: Some(Duration::from_secs(5)),
1387
+ cancellation_type: ActivityCancellationType::Abandon,
1388
+ ..Default::default()
1389
+ },
1390
+ );
1391
+ ctx.timer(Duration::from_secs(1)).await;
1392
+ act_fut.cancel();
1393
+ ctx.timer(Duration::from_secs(3)).await;
1394
+ let _ = act_fut.await;
1395
+ Ok(())
1396
+ }
1397
+ }
1398
+
1399
+ worker.register_workflow::<AbandonedActivitiesWorkflow>();
1400
+ let task_queue = worker.inner_mut().task_queue().to_owned();
1303
1401
  worker
1304
- .submit_wf(wfid, wf_type, vec![], Default::default())
1402
+ .submit_wf(
1403
+ wf_type,
1404
+ vec![],
1405
+ WorkflowStartOptions::new(task_queue, wfid).build(),
1406
+ )
1305
1407
  .await
1306
1408
  .unwrap();
1307
1409
  worker.run_until_done().await.unwrap();
1308
1410
  }
1309
1411
 
1412
+ #[workflow]
1413
+ #[derive(Default)]
1414
+ struct ImmediateActivityCancelationWorkflow;
1415
+
1416
+ #[workflow_methods]
1417
+ impl ImmediateActivityCancelationWorkflow {
1418
+ #[run(name = DEFAULT_WORKFLOW_TYPE)]
1419
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
1420
+ let cancel_activity_future =
1421
+ ctx.start_activity(StdActivities::default, (), ActivityOptions::default());
1422
+ cancel_activity_future.cancel();
1423
+ let _ = cancel_activity_future.await;
1424
+ Ok(())
1425
+ }
1426
+ }
1427
+
1310
1428
  #[tokio::test]
1311
1429
  async fn immediate_activity_cancelation() {
1312
- let func = WorkflowFunction::new(|ctx: WfContext| async move {
1313
- let cancel_activity_future = ctx.activity(ActivityOptions::default());
1314
- // Immediately cancel the activity
1315
- cancel_activity_future.cancel(&ctx);
1316
- cancel_activity_future.await;
1317
- Ok(().into())
1318
- });
1319
-
1320
1430
  let mut t = TestHistoryBuilder::default();
1321
1431
  t.add_by_type(EventType::WorkflowExecutionStarted);
1322
1432
  t.add_full_wf_task();
1323
1433
  t.add_workflow_execution_completed();
1324
1434
  let mut worker = build_fake_sdk(MockPollCfg::from_resps(t, [ResponseType::AllHistory]));
1325
- worker.register_wf(DEFAULT_WORKFLOW_TYPE, func);
1435
+ worker.register_workflow::<ImmediateActivityCancelationWorkflow>();
1326
1436
 
1327
1437
  let mut aai = ActivationAssertionsInterceptor::default();
1328
1438
  aai.then(|a| {