@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,8 +1,8 @@
1
1
  mod activities;
2
- mod appdata_propagation;
3
2
  mod cancel_external;
4
3
  mod cancel_wf;
5
4
  mod child_workflows;
5
+ mod client_interactions;
6
6
  mod continue_as_new;
7
7
  mod determinism;
8
8
  mod eager;
@@ -11,6 +11,7 @@ mod modify_wf_properties;
11
11
  mod nexus;
12
12
  mod patches;
13
13
  mod priority;
14
+ mod queries;
14
15
  mod replay;
15
16
  mod resets;
16
17
  mod signals;
@@ -20,26 +21,30 @@ mod upsert_search_attrs;
20
21
 
21
22
  use crate::{
22
23
  common::{
23
- CoreWfStarter, get_integ_runtime_options, history_from_proto_binary,
24
- init_core_and_create_wf, init_core_replay_preloaded, mock_sdk_cfg, prom_metrics,
24
+ CoreWfStarter, activity_functions::StdActivities, get_integ_runtime_options,
25
+ history_from_proto_binary, init_core_and_create_wf, init_core_replay_preloaded,
26
+ mock_sdk_cfg, prom_metrics,
25
27
  },
26
- integ_tests::{activity_functions::echo, metrics_tests},
28
+ integ_tests::metrics_tests,
27
29
  };
28
30
  use assert_matches::assert_matches;
29
31
  use std::{
30
32
  collections::{HashMap, HashSet},
33
+ sync::Arc,
31
34
  time::Duration,
32
35
  };
33
36
  use temporalio_client::{
34
- WfClientExt, WorkflowClientTrait, WorkflowExecutionResult, WorkflowOptions,
37
+ NamespacedClient, UntypedQuery, UntypedSignal, UntypedWorkflow, WorkflowExecutionInfo,
38
+ WorkflowQueryOptions, WorkflowSignalOptions, WorkflowStartOptions,
39
+ errors::WorkflowGetResultError, grpc::WorkflowService,
35
40
  };
36
41
  use temporalio_common::{
37
- errors::{PollError, WorkflowErrorType},
42
+ data_converters::RawValue,
38
43
  prost_dur,
39
44
  protos::{
40
45
  DEFAULT_WORKFLOW_TYPE, canned_histories,
41
46
  coresdk::{
42
- ActivityTaskCompletion, AsJsonPayloadExt, IntoCompletion,
47
+ ActivityTaskCompletion, IntoCompletion,
43
48
  activity_result::ActivityExecutionResult,
44
49
  workflow_activation::{WorkflowActivationJob, workflow_activation_job},
45
50
  workflow_commands::{
@@ -49,50 +54,59 @@ use temporalio_common::{
49
54
  workflow_completion::WorkflowActivationCompletion,
50
55
  },
51
56
  temporal::api::{
57
+ common::v1::WorkflowExecution,
52
58
  enums::v1::{CommandType, EventType},
53
59
  failure::v1::Failure,
54
60
  history::v1::history_event,
55
- query::v1::WorkflowQuery,
56
61
  sdk::v1::UserMetadata,
62
+ workflowservice::v1::ResetStickyTaskQueueRequest,
57
63
  },
58
64
  test_utils::schedule_activity_cmd,
59
65
  },
60
- worker::{
61
- PollerBehavior, WorkerDeploymentOptions, WorkerDeploymentVersion, WorkerTaskTypes,
62
- WorkerVersioningStrategy,
63
- },
66
+ worker::{WorkerDeploymentOptions, WorkerDeploymentVersion, WorkerTaskTypes},
64
67
  };
68
+ use temporalio_macros::{workflow, workflow_methods};
65
69
  use temporalio_sdk::{
66
- ActivityOptions, LocalActivityOptions, TimerOptions, WfContext, interceptors::WorkerInterceptor,
70
+ ActivityOptions, LocalActivityOptions, TimerOptions, WorkflowContext, WorkflowResult,
71
+ interceptors::WorkerInterceptor,
67
72
  };
68
73
  use temporalio_sdk_core::{
69
- CoreRuntime,
74
+ CoreRuntime, PollError, PollerBehavior, TunerHolder, WorkflowErrorType,
70
75
  replay::HistoryForReplay,
71
76
  test_help::{MockPollCfg, WorkerTestHelpers, drain_pollers_and_shutdown},
72
77
  };
73
78
  use tokio::{join, sync::Notify, time::sleep};
79
+ use tonic::IntoRequest;
74
80
  // TODO: We should get expected histories for these tests and confirm that the history at the end
75
81
  // matches.
76
82
 
83
+ #[workflow]
84
+ #[derive(Default)]
85
+ struct ParallelWorkflowsWf;
86
+
87
+ #[workflow_methods]
88
+ impl ParallelWorkflowsWf {
89
+ #[run]
90
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
91
+ ctx.timer(Duration::from_secs(1)).await;
92
+ Ok(())
93
+ }
94
+ }
95
+
77
96
  #[tokio::test]
78
97
  async fn parallel_workflows_same_queue() {
79
98
  let wf_name = "parallel_workflows_same_queue";
80
99
  let mut starter = CoreWfStarter::new(wf_name);
81
- starter
82
- .worker_config
83
- .task_types(WorkerTaskTypes::workflow_only());
100
+ starter.sdk_config.task_types = WorkerTaskTypes::workflow_only();
84
101
  let mut core = starter.worker().await;
85
102
 
86
- core.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
87
- ctx.timer(Duration::from_secs(1)).await;
88
- Ok(().into())
89
- });
103
+ core.register_workflow::<ParallelWorkflowsWf>();
104
+ let task_queue = starter.get_task_queue().to_owned();
90
105
  for i in 0..25 {
91
- core.submit_wf(
92
- format!("{wf_name}-{i}"),
93
- wf_name,
94
- vec![],
95
- starter.workflow_options.clone(),
106
+ core.submit_workflow(
107
+ ParallelWorkflowsWf::run,
108
+ (),
109
+ WorkflowStartOptions::new(task_queue.clone(), format!("{wf_name}-{i}")).build(),
96
110
  )
97
111
  .await
98
112
  .unwrap();
@@ -141,7 +155,7 @@ async fn fail_wf_task(#[values(true, false)] replay: bool) {
141
155
  attrs.first_execution_run_id = "run2".to_string();
142
156
  }
143
157
  let hist2 = HistoryForReplay::new(hist_proto, "fake".to_string());
144
- init_core_replay_preloaded("fail_wf_task", [hist, hist2])
158
+ Arc::new(init_core_replay_preloaded("fail_wf_task", [hist, hist2]))
145
159
  } else {
146
160
  let mut starter = init_core_and_create_wf("fail_wf_task").await;
147
161
  starter.get_worker().await
@@ -225,23 +239,26 @@ async fn signal_workflow() {
225
239
  .unwrap();
226
240
 
227
241
  // Send the signals to the server
228
- client
229
- .signal_workflow_execution(
230
- workflow_id.to_string(),
231
- res.run_id.to_string(),
232
- signal_id_1.to_string(),
233
- None,
234
- None,
242
+ let handle = WorkflowExecutionInfo {
243
+ namespace: client.namespace(),
244
+ workflow_id: workflow_id.clone(),
245
+ run_id: Some(res.run_id.clone()),
246
+ first_execution_run_id: None,
247
+ }
248
+ .bind_untyped(client.clone());
249
+ handle
250
+ .signal(
251
+ UntypedSignal::new(signal_id_1),
252
+ RawValue::empty(),
253
+ WorkflowSignalOptions::default(),
235
254
  )
236
255
  .await
237
256
  .unwrap();
238
- client
239
- .signal_workflow_execution(
240
- workflow_id.to_string(),
241
- res.run_id.to_string(),
242
- signal_id_2.to_string(),
243
- None,
244
- None,
257
+ handle
258
+ .signal(
259
+ UntypedSignal::new(signal_id_2),
260
+ RawValue::empty(),
261
+ WorkflowSignalOptions::default(),
245
262
  )
246
263
  .await
247
264
  .unwrap();
@@ -322,18 +339,21 @@ async fn signal_workflow_signal_not_handled_on_workflow_completion() {
322
339
  let run_id = res.run_id.clone();
323
340
 
324
341
  // Send the signal to the server
325
- starter
326
- .get_client()
327
- .await
328
- .signal_workflow_execution(
329
- workflow_id.clone(),
330
- res.run_id.to_string(),
331
- signal_id_1.to_string(),
332
- None,
333
- None,
334
- )
335
- .await
336
- .unwrap();
342
+ let sig_client = starter.get_client().await;
343
+ WorkflowExecutionInfo {
344
+ namespace: sig_client.namespace(),
345
+ workflow_id: workflow_id.clone(),
346
+ run_id: Some(res.run_id.clone()),
347
+ first_execution_run_id: None,
348
+ }
349
+ .bind_untyped(sig_client.clone())
350
+ .signal(
351
+ UntypedSignal::new(signal_id_1),
352
+ RawValue::empty(),
353
+ WorkflowSignalOptions::default(),
354
+ )
355
+ .await
356
+ .unwrap();
337
357
 
338
358
  // Send completion - not having seen a poll response with a signal in it yet (unhandled
339
359
  // command error will be logged as a warning and an eviction will be issued)
@@ -366,14 +386,10 @@ async fn wft_timeout_doesnt_create_unsolvable_autocomplete() {
366
386
  let signal_at_start = "at-start";
367
387
  let signal_at_complete = "at-complete";
368
388
  let mut wf_starter = CoreWfStarter::new("wft_timeout_doesnt_create_unsolvable_autocomplete");
369
- wf_starter
370
- .worker_config
371
- // Test needs eviction on and a short timeout
372
- .max_cached_workflows(0_usize)
373
- .max_outstanding_workflow_tasks(1_usize);
374
- wf_starter
375
- .worker_config
376
- .workflow_task_poller_behavior(PollerBehavior::SimpleMaximum(1_usize));
389
+ // Test needs eviction on and a short timeout
390
+ wf_starter.sdk_config.max_cached_workflows = 0_usize;
391
+ wf_starter.sdk_config.tuner = Arc::new(TunerHolder::fixed_size(1, 1, 1, 1));
392
+ wf_starter.sdk_config.workflow_task_poller_behavior = PollerBehavior::SimpleMaximum(1_usize);
377
393
  wf_starter.workflow_options.task_timeout = Some(Duration::from_secs(1));
378
394
  let core = wf_starter.get_worker().await;
379
395
  let client = wf_starter.get_client().await;
@@ -405,16 +421,20 @@ async fn wft_timeout_doesnt_create_unsolvable_autocomplete() {
405
421
  // Before polling for a task again, we start and complete the activity and send the
406
422
  // corresponding signals.
407
423
  let ac_task = core.poll_activity_task().await.unwrap();
408
- let rid = wf_task.run_id.clone();
424
+ let handle = WorkflowExecutionInfo {
425
+ namespace: client.namespace(),
426
+ workflow_id: wf_id.to_string(),
427
+ run_id: Some(wf_task.run_id.clone()),
428
+ first_execution_run_id: None,
429
+ }
430
+ .bind_untyped(client.clone());
409
431
  // Send the signals to the server & resolve activity -- sometimes this happens too fast
410
432
  sleep(Duration::from_millis(200)).await;
411
- client
412
- .signal_workflow_execution(
413
- wf_id.to_string(),
414
- rid,
415
- signal_at_start.to_string(),
416
- None,
417
- None,
433
+ handle
434
+ .signal(
435
+ UntypedSignal::new(signal_at_start),
436
+ RawValue::empty(),
437
+ WorkflowSignalOptions::default(),
418
438
  )
419
439
  .await
420
440
  .unwrap();
@@ -425,14 +445,11 @@ async fn wft_timeout_doesnt_create_unsolvable_autocomplete() {
425
445
  })
426
446
  .await
427
447
  .unwrap();
428
- let rid = wf_task.run_id.clone();
429
- client
430
- .signal_workflow_execution(
431
- wf_id.to_string(),
432
- rid,
433
- signal_at_complete.to_string(),
434
- None,
435
- None,
448
+ handle
449
+ .signal(
450
+ UntypedSignal::new(signal_at_complete),
451
+ RawValue::empty(),
452
+ WorkflowSignalOptions::default(),
436
453
  )
437
454
  .await
438
455
  .unwrap();
@@ -475,36 +492,49 @@ async fn wft_timeout_doesnt_create_unsolvable_autocomplete() {
475
492
  /// overflow. This test intentionally makes completes slower than polls to evaluate that.
476
493
  ///
477
494
  /// It's expected that this test may generate some task timeouts.
495
+ #[workflow]
496
+ #[derive(Default)]
497
+ struct SlowCompletesWf;
498
+
499
+ #[workflow_methods]
500
+ impl SlowCompletesWf {
501
+ #[run]
502
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
503
+ for _ in 0..3 {
504
+ ctx.start_activity(
505
+ StdActivities::echo,
506
+ "hi!".to_string(),
507
+ ActivityOptions {
508
+ start_to_close_timeout: Some(Duration::from_secs(5)),
509
+ ..Default::default()
510
+ },
511
+ )
512
+ .await
513
+ .map_err(|e| anyhow::anyhow!("{e}"))?;
514
+ ctx.timer(Duration::from_secs(1)).await;
515
+ }
516
+ Ok(())
517
+ }
518
+ }
519
+
478
520
  #[tokio::test]
479
521
  async fn slow_completes_with_small_cache() {
480
522
  let wf_name = "slow_completes_with_small_cache";
481
523
  let mut starter = CoreWfStarter::new(wf_name);
482
- starter
483
- .worker_config
484
- .max_outstanding_workflow_tasks(5_usize)
485
- .max_cached_workflows(5_usize);
524
+ starter.sdk_config.tuner = Arc::new(TunerHolder::fixed_size(5, 10, 1, 1));
525
+ starter.sdk_config.max_cached_workflows = 5_usize;
486
526
  let mut worker = starter.worker().await;
487
- worker.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
488
- for _ in 0..3 {
489
- ctx.activity(ActivityOptions {
490
- activity_type: "echo_activity".to_string(),
491
- start_to_close_timeout: Some(Duration::from_secs(5)),
492
- input: "hi!".as_json_payload().expect("serializes fine"),
493
- ..Default::default()
494
- })
495
- .await;
496
- ctx.timer(Duration::from_secs(1)).await;
497
- }
498
- Ok(().into())
499
- });
500
- worker.register_activity("echo_activity", echo);
527
+
528
+ worker.register_activities(StdActivities);
529
+
530
+ worker.register_workflow::<SlowCompletesWf>();
531
+ let task_queue = starter.get_task_queue().to_owned();
501
532
  for i in 0..20 {
502
533
  worker
503
- .submit_wf(
504
- format!("{wf_name}_{i}"),
505
- wf_name.to_owned(),
506
- vec![],
507
- WorkflowOptions::default(),
534
+ .submit_workflow(
535
+ SlowCompletesWf::run,
536
+ (),
537
+ WorkflowStartOptions::new(task_queue.clone(), format!("{wf_name}_{i}")).build(),
508
538
  )
509
539
  .await
510
540
  .unwrap();
@@ -530,24 +560,26 @@ async fn slow_completes_with_small_cache() {
530
560
  async fn deployment_version_correct_in_wf_info(#[values(true, false)] use_only_build_id: bool) {
531
561
  let wf_type = "deployment_version_correct_in_wf_info";
532
562
  let mut starter = CoreWfStarter::new(wf_type);
533
- let version_strat = if use_only_build_id {
534
- WorkerVersioningStrategy::None {
535
- build_id: "1.0".to_owned(),
563
+ starter.sdk_config.deployment_options = if use_only_build_id {
564
+ WorkerDeploymentOptions {
565
+ version: WorkerDeploymentVersion {
566
+ deployment_name: "".to_string(),
567
+ build_id: "1.0".to_string(),
568
+ },
569
+ use_worker_versioning: false,
570
+ default_versioning_behavior: None,
536
571
  }
537
572
  } else {
538
- WorkerVersioningStrategy::WorkerDeploymentBased(WorkerDeploymentOptions {
573
+ WorkerDeploymentOptions {
539
574
  version: WorkerDeploymentVersion {
540
575
  deployment_name: "deployment-1".to_string(),
541
576
  build_id: "1.0".to_string(),
542
577
  },
543
578
  use_worker_versioning: false,
544
579
  default_versioning_behavior: None,
545
- })
580
+ }
546
581
  };
547
- starter
548
- .worker_config
549
- .versioning_strategy(version_strat)
550
- .task_types(WorkerTaskTypes::workflow_only());
582
+ starter.sdk_config.task_types = WorkerTaskTypes::workflow_only();
551
583
  let core = starter.get_worker().await;
552
584
  starter.start_wf().await;
553
585
  let client = starter.get_client().await;
@@ -577,15 +609,19 @@ async fn deployment_version_correct_in_wf_info(#[values(true, false)] use_only_b
577
609
  .unwrap();
578
610
 
579
611
  // Ensure a query on first wft also sees the correct id
612
+ let query_handle = WorkflowExecutionInfo {
613
+ namespace: client.namespace(),
614
+ workflow_id: workflow_id.clone(),
615
+ run_id: Some(res.run_id.clone()),
616
+ first_execution_run_id: None,
617
+ }
618
+ .bind_untyped(client.clone());
580
619
  let query_fut = async {
581
- client
582
- .query_workflow_execution(
583
- workflow_id.clone(),
584
- res.run_id.to_string(),
585
- WorkflowQuery {
586
- query_type: "q1".to_string(),
587
- ..Default::default()
588
- },
620
+ query_handle
621
+ .query(
622
+ UntypedQuery::new("q1"),
623
+ RawValue::empty(),
624
+ WorkflowQueryOptions::default(),
589
625
  )
590
626
  .await
591
627
  .unwrap()
@@ -631,39 +667,49 @@ async fn deployment_version_correct_in_wf_info(#[values(true, false)] use_only_b
631
667
  };
632
668
  join!(query_fut, complete_fut);
633
669
  starter.shutdown().await;
634
- client
635
- .reset_sticky_task_queue(workflow_id.clone(), "".to_string())
636
- .await
637
- .unwrap();
670
+ WorkflowService::reset_sticky_task_queue(
671
+ &mut client.clone(),
672
+ ResetStickyTaskQueueRequest {
673
+ namespace: client.namespace(),
674
+ execution: Some(WorkflowExecution {
675
+ workflow_id: workflow_id.clone(),
676
+ run_id: "".to_string(),
677
+ }),
678
+ }
679
+ .into_request(),
680
+ )
681
+ .await
682
+ .unwrap();
638
683
 
639
684
  let mut starter = starter.clone_no_worker();
640
- let version_strat = if use_only_build_id {
641
- WorkerVersioningStrategy::None {
642
- build_id: "2.0".to_owned(),
685
+ starter.sdk_config.deployment_options = if use_only_build_id {
686
+ WorkerDeploymentOptions {
687
+ version: WorkerDeploymentVersion {
688
+ deployment_name: "".to_string(),
689
+ build_id: "2.0".to_string(),
690
+ },
691
+ use_worker_versioning: false,
692
+ default_versioning_behavior: None,
643
693
  }
644
694
  } else {
645
- WorkerVersioningStrategy::WorkerDeploymentBased(WorkerDeploymentOptions {
695
+ WorkerDeploymentOptions {
646
696
  version: WorkerDeploymentVersion {
647
697
  deployment_name: "deployment-1".to_string(),
648
698
  build_id: "2.0".to_string(),
649
699
  },
650
700
  use_worker_versioning: false,
651
701
  default_versioning_behavior: None,
652
- })
702
+ }
653
703
  };
654
- starter.worker_config.versioning_strategy(version_strat);
655
704
 
656
705
  let core = starter.get_worker().await;
657
706
 
658
707
  let query_fut = async {
659
- client
660
- .query_workflow_execution(
661
- workflow_id.clone(),
662
- res.run_id.to_string(),
663
- WorkflowQuery {
664
- query_type: "q2".to_string(),
665
- ..Default::default()
666
- },
708
+ query_handle
709
+ .query(
710
+ UntypedQuery::new("q2"),
711
+ RawValue::empty(),
712
+ WorkflowQueryOptions::default(),
667
713
  )
668
714
  .await
669
715
  .unwrap()
@@ -732,12 +778,11 @@ async fn deployment_version_correct_in_wf_info(#[values(true, false)] use_only_b
732
778
  join!(query_fut, complete_fut);
733
779
 
734
780
  client
735
- .signal_workflow_execution(
736
- workflow_id.clone(),
737
- "".to_string(),
738
- "whatever".to_string(),
739
- None,
740
- None,
781
+ .get_workflow_handle::<UntypedWorkflow>(&workflow_id)
782
+ .signal(
783
+ UntypedSignal::new("whatever"),
784
+ RawValue::empty(),
785
+ WorkflowSignalOptions::default(),
741
786
  )
742
787
  .await
743
788
  .unwrap();
@@ -761,6 +806,8 @@ async fn deployment_version_correct_in_wf_info(#[values(true, false)] use_only_b
761
806
  core.complete_execution(&res.run_id).await;
762
807
  }
763
808
 
809
+ const NONDETERMINISM_WF_NAME: &str = "nondeterminism_errors_fail_workflow_when_configured_to";
810
+
764
811
  #[rstest::rstest]
765
812
  #[tokio::test]
766
813
  async fn nondeterminism_errors_fail_workflow_when_configured_to(
@@ -768,29 +815,36 @@ async fn nondeterminism_errors_fail_workflow_when_configured_to(
768
815
  ) {
769
816
  let (telemopts, addr, _aborter) = prom_metrics(None);
770
817
  let rt = CoreRuntime::new_assume_tokio(get_integ_runtime_options(telemopts)).unwrap();
771
- let wf_name = "nondeterminism_errors_fail_workflow_when_configured_to";
818
+ let wf_name = NONDETERMINISM_WF_NAME;
772
819
  let mut starter = CoreWfStarter::new_with_runtime(wf_name, rt);
773
- starter
774
- .worker_config
775
- .task_types(WorkerTaskTypes::workflow_only());
820
+ starter.sdk_config.task_types = WorkerTaskTypes::workflow_only();
776
821
  let typeset = HashSet::from([WorkflowErrorType::Nondeterminism]);
777
822
  if whole_worker {
778
- starter.worker_config.workflow_failure_errors(typeset);
823
+ starter.sdk_config.workflow_failure_errors = typeset;
779
824
  } else {
780
- starter
781
- .worker_config
782
- .workflow_types_to_failure_errors(HashMap::from([(wf_name.to_owned(), typeset)]));
825
+ starter.sdk_config.workflow_types_to_failure_errors =
826
+ HashMap::from([(wf_name.to_owned(), typeset)]);
783
827
  }
784
828
  let wf_id = starter.get_task_queue().to_owned();
785
829
  let mut worker = starter.worker().await;
786
830
  worker.fetch_results = false;
787
831
 
788
- worker.register_wf(wf_name.to_owned(), move |ctx: WfContext| async move {
789
- ctx.timer(Duration::from_secs(1000)).await;
790
- Ok(().into())
791
- });
832
+ #[workflow]
833
+ #[derive(Default)]
834
+ struct NondeterminismTimerWf;
835
+
836
+ #[workflow_methods]
837
+ impl NondeterminismTimerWf {
838
+ #[run(name = NONDETERMINISM_WF_NAME)]
839
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
840
+ ctx.timer(Duration::from_secs(1000)).await;
841
+ Ok(())
842
+ }
843
+ }
844
+
845
+ worker.register_workflow::<NondeterminismTimerWf>();
792
846
  let client = starter.get_client().await;
793
- let core_worker = worker.core_worker.clone();
847
+ let core_worker = worker.core_worker();
794
848
  starter.start_with_worker(wf_name, &mut worker).await;
795
849
 
796
850
  let stopper = async {
@@ -815,23 +869,53 @@ async fn nondeterminism_errors_fail_workflow_when_configured_to(
815
869
 
816
870
  // Restart the worker with a new, incompatible wf definition which will cause nondeterminism
817
871
  let mut starter = starter.clone_no_worker();
872
+ starter.sdk_config.register_activities(StdActivities);
818
873
  let mut worker = starter.worker().await;
819
- worker.register_wf(wf_name.to_owned(), move |ctx: WfContext| async move {
820
- ctx.activity(ActivityOptions {
821
- activity_type: "echo_activity".to_string(),
822
- start_to_close_timeout: Some(Duration::from_secs(5)),
823
- ..Default::default()
824
- })
825
- .await;
826
- Ok(().into())
827
- });
874
+
875
+ #[workflow]
876
+ #[derive(Default)]
877
+ struct NondeterminismActivityWf;
878
+
879
+ #[workflow_methods]
880
+ impl NondeterminismActivityWf {
881
+ #[run(name = NONDETERMINISM_WF_NAME)]
882
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
883
+ ctx.start_activity(
884
+ StdActivities::echo,
885
+ "hi".to_owned(),
886
+ ActivityOptions {
887
+ start_to_close_timeout: Some(Duration::from_secs(5)),
888
+ ..Default::default()
889
+ },
890
+ )
891
+ .await
892
+ .map_err(|e| anyhow::anyhow!("{e}"))?;
893
+ Ok(())
894
+ }
895
+ }
896
+
897
+ worker.register_workflow::<NondeterminismActivityWf>();
828
898
  // We need to generate a task so that we'll encounter the error (first avoid WFT timeout)
899
+ WorkflowService::reset_sticky_task_queue(
900
+ &mut client.clone(),
901
+ ResetStickyTaskQueueRequest {
902
+ namespace: client.namespace(),
903
+ execution: Some(WorkflowExecution {
904
+ workflow_id: wf_id.clone(),
905
+ run_id: "".to_string(),
906
+ }),
907
+ }
908
+ .into_request(),
909
+ )
910
+ .await
911
+ .unwrap();
829
912
  client
830
- .reset_sticky_task_queue(wf_id.clone(), "".to_string())
831
- .await
832
- .unwrap();
833
- client
834
- .signal_workflow_execution(wf_id.clone(), "".to_string(), "hi".to_string(), None, None)
913
+ .get_workflow_handle::<UntypedWorkflow>(&wf_id)
914
+ .signal(
915
+ UntypedSignal::new("hi"),
916
+ RawValue::empty(),
917
+ WorkflowSignalOptions::default(),
918
+ )
835
919
  .await
836
920
  .unwrap();
837
921
  worker.expect_workflow_completion(&wf_id, None);
@@ -847,71 +931,105 @@ async fn nondeterminism_errors_fail_workflow_when_configured_to(
847
931
  assert!(body.contains(&match_this));
848
932
  }
849
933
 
934
+ const HISTORY_OUT_OF_ORDER_WF_NAME: &str = "history_out_of_order_on_restart";
935
+
850
936
  #[tokio::test]
851
937
  async fn history_out_of_order_on_restart() {
852
- let wf_name = "history_out_of_order_on_restart";
938
+ let wf_name = HISTORY_OUT_OF_ORDER_WF_NAME;
853
939
  let mut starter = CoreWfStarter::new(wf_name);
854
- starter
855
- .worker_config
856
- .workflow_failure_errors([WorkflowErrorType::Nondeterminism]);
940
+ starter.sdk_config.workflow_failure_errors = HashSet::from([WorkflowErrorType::Nondeterminism]);
857
941
  let mut worker = starter.worker().await;
858
942
  let mut starter2 = starter.clone_no_worker();
859
943
  let mut worker2 = starter2.worker().await;
860
944
 
861
- static HIT_SLEEP: Notify = Notify::const_new();
945
+ let hit_sleep = Arc::new(Notify::new());
946
+ let hit_sleep_clone1 = hit_sleep.clone();
947
+ let hit_sleep_clone2 = hit_sleep.clone();
862
948
 
863
- worker.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
864
- ctx.local_activity(LocalActivityOptions {
865
- activity_type: "echo".to_owned(),
866
- input: "hi".as_json_payload().unwrap(),
867
- start_to_close_timeout: Some(Duration::from_secs(5)),
868
- ..Default::default()
869
- })
870
- .await;
871
- ctx.activity(ActivityOptions {
872
- activity_type: "echo".to_owned(),
873
- input: "hi".as_json_payload().unwrap(),
874
- start_to_close_timeout: Some(Duration::from_secs(5)),
875
- ..Default::default()
876
- })
877
- .await;
878
- // Interrupt this sleep on first go
879
- HIT_SLEEP.notify_one();
880
- ctx.timer(Duration::from_secs(5)).await;
881
- Ok(().into())
882
- });
883
- worker.register_activity("echo", echo);
884
-
885
- worker2.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
886
- ctx.local_activity(LocalActivityOptions {
887
- activity_type: "echo".to_owned(),
888
- input: "hi".as_json_payload().unwrap(),
889
- start_to_close_timeout: Some(Duration::from_secs(5)),
890
- ..Default::default()
891
- })
892
- .await;
893
- // Timer is added after restarting workflow
894
- ctx.timer(Duration::from_secs(1)).await;
895
- ctx.activity(ActivityOptions {
896
- activity_type: "echo".to_owned(),
897
- input: "hi".as_json_payload().unwrap(),
898
- start_to_close_timeout: Some(Duration::from_secs(5)),
899
- ..Default::default()
900
- })
901
- .await;
902
- ctx.timer(Duration::from_secs(2)).await;
903
- Ok(().into())
949
+ #[workflow]
950
+ struct HistoryOutOfOrderWf1 {
951
+ hit_sleep: Arc<Notify>,
952
+ }
953
+
954
+ #[workflow_methods(factory_only)]
955
+ impl HistoryOutOfOrderWf1 {
956
+ #[run(name = HISTORY_OUT_OF_ORDER_WF_NAME)]
957
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
958
+ ctx.start_local_activity(
959
+ StdActivities::echo,
960
+ "hi".to_string(),
961
+ LocalActivityOptions {
962
+ start_to_close_timeout: Some(Duration::from_secs(5)),
963
+ ..Default::default()
964
+ },
965
+ )
966
+ .await
967
+ .map_err(|e| anyhow::anyhow!("{e}"))?;
968
+ ctx.start_activity(
969
+ StdActivities::echo,
970
+ "hi".to_string(),
971
+ ActivityOptions {
972
+ start_to_close_timeout: Some(Duration::from_secs(5)),
973
+ ..Default::default()
974
+ },
975
+ )
976
+ .await
977
+ .map_err(|e| anyhow::anyhow!("{e}"))?;
978
+ ctx.state(|wf| wf.hit_sleep.notify_one());
979
+ ctx.timer(Duration::from_secs(5)).await;
980
+ Ok(())
981
+ }
982
+ }
983
+
984
+ #[workflow]
985
+ #[derive(Default)]
986
+ struct HistoryOutOfOrderWf2;
987
+
988
+ #[workflow_methods]
989
+ impl HistoryOutOfOrderWf2 {
990
+ #[run(name = HISTORY_OUT_OF_ORDER_WF_NAME)]
991
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
992
+ ctx.start_local_activity(
993
+ StdActivities::echo,
994
+ "hi".to_string(),
995
+ LocalActivityOptions {
996
+ start_to_close_timeout: Some(Duration::from_secs(5)),
997
+ ..Default::default()
998
+ },
999
+ )
1000
+ .await
1001
+ .map_err(|e| anyhow::anyhow!("{e}"))?;
1002
+ // Timer is added after restarting workflow
1003
+ ctx.timer(Duration::from_secs(1)).await;
1004
+ ctx.start_activity(
1005
+ StdActivities::echo,
1006
+ "hi".to_string(),
1007
+ ActivityOptions {
1008
+ start_to_close_timeout: Some(Duration::from_secs(5)),
1009
+ ..Default::default()
1010
+ },
1011
+ )
1012
+ .await
1013
+ .map_err(|e| anyhow::anyhow!("{e}"))?;
1014
+ ctx.timer(Duration::from_secs(2)).await;
1015
+ Ok(())
1016
+ }
1017
+ }
1018
+
1019
+ worker.register_activities(StdActivities);
1020
+ worker2.register_activities(StdActivities);
1021
+ worker.register_workflow_with_factory(move || HistoryOutOfOrderWf1 {
1022
+ hit_sleep: hit_sleep_clone1.clone(),
904
1023
  });
905
- worker2.register_activity("echo", echo);
1024
+ worker2.register_workflow::<HistoryOutOfOrderWf2>();
1025
+ let task_queue = starter.get_task_queue().to_owned();
906
1026
  worker
907
- .submit_wf(
908
- wf_name.to_owned(),
909
- wf_name.to_owned(),
910
- vec![],
911
- WorkflowOptions {
912
- execution_timeout: Some(Duration::from_secs(20)),
913
- ..Default::default()
914
- },
1027
+ .submit_workflow(
1028
+ HistoryOutOfOrderWf1::run,
1029
+ (),
1030
+ WorkflowStartOptions::new(task_queue, wf_name.to_owned())
1031
+ .execution_timeout(Duration::from_secs(20))
1032
+ .build(),
915
1033
  )
916
1034
  .await
917
1035
  .unwrap();
@@ -921,7 +1039,7 @@ async fn history_out_of_order_on_restart() {
921
1039
  };
922
1040
  let w2 = async {
923
1041
  // wait to hit sleep
924
- HIT_SLEEP.notified().await;
1042
+ hit_sleep_clone2.notified().await;
925
1043
  starter.shutdown().await;
926
1044
  // start new worker
927
1045
  worker2.expect_workflow_completion(wf_name, None);
@@ -932,12 +1050,9 @@ async fn history_out_of_order_on_restart() {
932
1050
  let handle = starter
933
1051
  .get_client()
934
1052
  .await
935
- .get_untyped_workflow_handle(wf_name, "");
936
- let res = handle
937
- .get_workflow_result(Default::default())
938
- .await
939
- .unwrap();
940
- assert_matches!(res, WorkflowExecutionResult::Failed(_));
1053
+ .get_workflow_handle::<UntypedWorkflow>(wf_name);
1054
+ let res = handle.get_result(Default::default()).await;
1055
+ assert_matches!(res, Err(WorkflowGetResultError::Failed(_)));
941
1056
  }
942
1057
 
943
1058
  #[tokio::test]
@@ -945,7 +1060,6 @@ async fn pass_timer_summary_to_metadata() {
945
1060
  let t = canned_histories::single_timer("1");
946
1061
  let mut mock_cfg = MockPollCfg::from_hist_builder(t);
947
1062
  let wf_id = mock_cfg.hists[0].wf_id.clone();
948
- let wf_type = DEFAULT_WORKFLOW_TYPE;
949
1063
  let expected_user_metadata = Some(UserMetadata {
950
1064
  summary: Some(b"timer summary".into()),
951
1065
  details: None,
@@ -966,21 +1080,30 @@ async fn pass_timer_summary_to_metadata() {
966
1080
  });
967
1081
  });
968
1082
 
1083
+ #[workflow]
1084
+ #[derive(Default)]
1085
+ struct PassTimerSummaryWf;
1086
+
1087
+ #[workflow_methods]
1088
+ impl PassTimerSummaryWf {
1089
+ #[run(name = DEFAULT_WORKFLOW_TYPE)]
1090
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
1091
+ ctx.timer(TimerOptions {
1092
+ duration: Duration::from_secs(1),
1093
+ summary: Some("timer summary".to_string()),
1094
+ })
1095
+ .await;
1096
+ Ok(())
1097
+ }
1098
+ }
1099
+
969
1100
  let mut worker = mock_sdk_cfg(mock_cfg, |_| {});
970
- worker.register_wf(wf_type, |ctx: WfContext| async move {
971
- ctx.timer(TimerOptions {
972
- duration: Duration::from_secs(1),
973
- summary: Some("timer summary".to_string()),
974
- })
975
- .await;
976
- Ok(().into())
977
- });
1101
+ worker.register_workflow::<PassTimerSummaryWf>();
978
1102
  worker
979
1103
  .submit_wf(
980
- wf_id.to_owned(),
981
- wf_type.to_owned(),
1104
+ DEFAULT_WORKFLOW_TYPE.to_owned(),
982
1105
  vec![],
983
- WorkflowOptions::default(),
1106
+ WorkflowStartOptions::new("fake_tq".to_owned(), wf_id.to_owned()).build(),
984
1107
  )
985
1108
  .await
986
1109
  .unwrap();