@temporalio/core-bridge 1.15.0 → 1.16.1

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 (209) hide show
  1. package/Cargo.lock +172 -70
  2. package/lib/native.d.ts +1 -1
  3. package/package.json +2 -2
  4. package/releases/aarch64-apple-darwin/index.node +0 -0
  5. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  6. package/releases/x86_64-apple-darwin/index.node +0 -0
  7. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  8. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  9. package/sdk-core/.github/workflows/per-pr.yml +6 -6
  10. package/sdk-core/AGENTS.md +41 -30
  11. package/sdk-core/Cargo.toml +3 -0
  12. package/sdk-core/README.md +15 -9
  13. package/sdk-core/crates/client/Cargo.toml +4 -0
  14. package/sdk-core/crates/client/README.md +139 -0
  15. package/sdk-core/crates/client/src/async_activity_handle.rs +297 -0
  16. package/sdk-core/crates/client/src/callback_based.rs +7 -0
  17. package/sdk-core/crates/client/src/errors.rs +294 -0
  18. package/sdk-core/crates/client/src/{raw.rs → grpc.rs} +280 -159
  19. package/sdk-core/crates/client/src/lib.rs +920 -1326
  20. package/sdk-core/crates/client/src/metrics.rs +24 -33
  21. package/sdk-core/crates/client/src/options_structs.rs +457 -0
  22. package/sdk-core/crates/client/src/replaceable.rs +5 -4
  23. package/sdk-core/crates/client/src/request_extensions.rs +8 -9
  24. package/sdk-core/crates/client/src/retry.rs +99 -54
  25. package/sdk-core/crates/client/src/{worker/mod.rs → worker.rs} +1 -1
  26. package/sdk-core/crates/client/src/workflow_handle.rs +826 -0
  27. package/sdk-core/crates/common/Cargo.toml +61 -2
  28. package/sdk-core/crates/common/build.rs +742 -12
  29. package/sdk-core/crates/common/protos/api_upstream/.github/workflows/ci.yml +2 -0
  30. package/sdk-core/crates/common/protos/api_upstream/Makefile +2 -1
  31. package/sdk-core/crates/common/protos/api_upstream/buf.yaml +0 -3
  32. package/sdk-core/crates/common/protos/api_upstream/cmd/check-path-conflicts/main.go +137 -0
  33. package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv2.json +1166 -770
  34. package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv3.yaml +1243 -750
  35. package/sdk-core/crates/common/protos/api_upstream/temporal/api/deployment/v1/message.proto +2 -2
  36. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/workflow.proto +4 -3
  37. package/sdk-core/crates/common/protos/api_upstream/temporal/api/failure/v1/message.proto +1 -0
  38. package/sdk-core/crates/common/protos/api_upstream/temporal/api/history/v1/message.proto +4 -0
  39. package/sdk-core/crates/common/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
  40. package/sdk-core/crates/common/protos/api_upstream/temporal/api/nexus/v1/message.proto +16 -1
  41. package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +64 -6
  42. package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +88 -33
  43. package/sdk-core/crates/common/protos/local/temporal/sdk/core/nexus/nexus.proto +4 -2
  44. package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +4 -0
  45. package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +5 -5
  46. package/sdk-core/crates/common/src/activity_definition.rs +20 -0
  47. package/sdk-core/crates/common/src/data_converters.rs +770 -0
  48. package/sdk-core/crates/common/src/envconfig.rs +5 -0
  49. package/sdk-core/crates/common/src/lib.rs +15 -211
  50. package/sdk-core/crates/common/src/payload_visitor.rs +648 -0
  51. package/sdk-core/crates/common/src/priority.rs +110 -0
  52. package/sdk-core/crates/common/src/protos/canned_histories.rs +3 -0
  53. package/sdk-core/crates/common/src/protos/history_builder.rs +45 -0
  54. package/sdk-core/crates/common/src/protos/history_info.rs +2 -0
  55. package/sdk-core/crates/common/src/protos/mod.rs +122 -27
  56. package/sdk-core/crates/common/src/protos/task_token.rs +3 -3
  57. package/sdk-core/crates/common/src/protos/utilities.rs +11 -0
  58. package/sdk-core/crates/{sdk-core → common}/src/telemetry/log_export.rs +5 -7
  59. package/sdk-core/crates/common/src/telemetry/metrics/core.rs +125 -0
  60. package/sdk-core/crates/common/src/telemetry/metrics.rs +268 -223
  61. package/sdk-core/crates/{sdk-core → common}/src/telemetry/otel.rs +8 -13
  62. package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_meter.rs +49 -50
  63. package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_server.rs +2 -3
  64. package/sdk-core/crates/common/src/telemetry.rs +264 -4
  65. package/sdk-core/crates/common/src/worker.rs +68 -603
  66. package/sdk-core/crates/common/src/workflow_definition.rs +60 -0
  67. package/sdk-core/crates/macros/Cargo.toml +5 -1
  68. package/sdk-core/crates/macros/src/activities_definitions.rs +585 -0
  69. package/sdk-core/crates/macros/src/fsm_impl.rs +507 -0
  70. package/sdk-core/crates/macros/src/lib.rs +138 -512
  71. package/sdk-core/crates/macros/src/macro_utils.rs +106 -0
  72. package/sdk-core/crates/macros/src/workflow_definitions.rs +1224 -0
  73. package/sdk-core/crates/sdk/Cargo.toml +19 -6
  74. package/sdk-core/crates/sdk/README.md +415 -0
  75. package/sdk-core/crates/sdk/src/activities.rs +417 -0
  76. package/sdk-core/crates/sdk/src/interceptors.rs +1 -1
  77. package/sdk-core/crates/sdk/src/lib.rs +757 -442
  78. package/sdk-core/crates/sdk/src/workflow_context/options.rs +45 -35
  79. package/sdk-core/crates/sdk/src/workflow_context.rs +1033 -289
  80. package/sdk-core/crates/sdk/src/workflow_future.rs +277 -213
  81. package/sdk-core/crates/sdk/src/workflows.rs +711 -0
  82. package/sdk-core/crates/sdk-core/Cargo.toml +57 -64
  83. package/sdk-core/crates/sdk-core/benches/workflow_replay_bench.rs +41 -35
  84. package/sdk-core/crates/sdk-core/machine_coverage/ActivityMachine_Coverage.puml +1 -1
  85. package/sdk-core/crates/sdk-core/src/abstractions.rs +6 -10
  86. package/sdk-core/crates/sdk-core/src/core_tests/activity_tasks.rs +6 -5
  87. package/sdk-core/crates/sdk-core/src/core_tests/mod.rs +13 -15
  88. package/sdk-core/crates/sdk-core/src/core_tests/queries.rs +21 -25
  89. package/sdk-core/crates/sdk-core/src/core_tests/replay_flag.rs +7 -10
  90. package/sdk-core/crates/sdk-core/src/core_tests/updates.rs +14 -17
  91. package/sdk-core/crates/sdk-core/src/core_tests/workers.rs +493 -26
  92. package/sdk-core/crates/sdk-core/src/core_tests/workflow_tasks.rs +4 -8
  93. package/sdk-core/crates/sdk-core/src/ephemeral_server/mod.rs +7 -7
  94. package/sdk-core/crates/sdk-core/src/histfetch.rs +20 -10
  95. package/sdk-core/crates/sdk-core/src/lib.rs +41 -111
  96. package/sdk-core/crates/sdk-core/src/pollers/mod.rs +4 -9
  97. package/sdk-core/crates/sdk-core/src/pollers/poll_buffer.rs +118 -19
  98. package/sdk-core/crates/sdk-core/src/protosext/mod.rs +2 -2
  99. package/sdk-core/crates/sdk-core/src/replay/mod.rs +14 -5
  100. package/sdk-core/crates/sdk-core/src/telemetry/metrics.rs +179 -196
  101. package/sdk-core/crates/sdk-core/src/telemetry/mod.rs +3 -280
  102. package/sdk-core/crates/sdk-core/src/test_help/integ_helpers.rs +6 -9
  103. package/sdk-core/crates/sdk-core/src/test_help/unit_helpers.rs +3 -6
  104. package/sdk-core/crates/sdk-core/src/worker/activities/local_activities.rs +11 -14
  105. package/sdk-core/crates/sdk-core/src/worker/activities.rs +16 -19
  106. package/sdk-core/crates/sdk-core/src/worker/client/mocks.rs +9 -5
  107. package/sdk-core/crates/sdk-core/src/worker/client.rs +103 -81
  108. package/sdk-core/crates/sdk-core/src/worker/heartbeat.rs +7 -11
  109. package/sdk-core/crates/sdk-core/src/worker/mod.rs +1124 -229
  110. package/sdk-core/crates/sdk-core/src/worker/nexus.rs +145 -23
  111. package/sdk-core/crates/sdk-core/src/worker/slot_provider.rs +2 -2
  112. package/sdk-core/crates/sdk-core/src/worker/tuner/fixed_size.rs +2 -2
  113. package/sdk-core/crates/sdk-core/src/worker/tuner/resource_based.rs +13 -13
  114. package/sdk-core/crates/sdk-core/src/worker/tuner.rs +28 -8
  115. package/sdk-core/crates/sdk-core/src/worker/workflow/driven_workflow.rs +9 -3
  116. package/sdk-core/crates/sdk-core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +21 -22
  117. package/sdk-core/crates/sdk-core/src/worker/workflow/machines/workflow_machines.rs +19 -4
  118. package/sdk-core/crates/sdk-core/src/worker/workflow/managed_run.rs +14 -18
  119. package/sdk-core/crates/sdk-core/src/worker/workflow/mod.rs +4 -6
  120. package/sdk-core/crates/sdk-core/src/worker/workflow/run_cache.rs +4 -7
  121. package/sdk-core/crates/sdk-core/src/worker/workflow/wft_extraction.rs +2 -4
  122. package/sdk-core/crates/sdk-core/src/worker/workflow/wft_poller.rs +8 -9
  123. package/sdk-core/crates/sdk-core/src/worker/workflow/workflow_stream.rs +1 -3
  124. package/sdk-core/crates/sdk-core/tests/activities_procmacro.rs +6 -0
  125. package/sdk-core/crates/sdk-core/tests/activities_trybuild/basic_pass.rs +54 -0
  126. package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.rs +18 -0
  127. package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.stderr +5 -0
  128. package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.rs +14 -0
  129. package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.stderr +5 -0
  130. package/sdk-core/crates/sdk-core/tests/activities_trybuild/multi_arg_pass.rs +48 -0
  131. package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_input_pass.rs +14 -0
  132. package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_return_type_pass.rs +19 -0
  133. package/sdk-core/crates/sdk-core/tests/cloud_tests.rs +14 -5
  134. package/sdk-core/crates/sdk-core/tests/common/activity_functions.rs +55 -0
  135. package/sdk-core/crates/sdk-core/tests/common/mod.rs +241 -196
  136. package/sdk-core/crates/sdk-core/tests/common/workflows.rs +41 -28
  137. package/sdk-core/crates/sdk-core/tests/global_metric_tests.rs +3 -5
  138. package/sdk-core/crates/sdk-core/tests/heavy_tests/fuzzy_workflow.rs +73 -64
  139. package/sdk-core/crates/sdk-core/tests/heavy_tests.rs +298 -252
  140. package/sdk-core/crates/sdk-core/tests/integ_tests/async_activity_client_tests.rs +230 -0
  141. package/sdk-core/crates/sdk-core/tests/integ_tests/client_tests.rs +94 -57
  142. package/sdk-core/crates/sdk-core/tests/integ_tests/data_converter_tests.rs +381 -0
  143. package/sdk-core/crates/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +16 -12
  144. package/sdk-core/crates/sdk-core/tests/integ_tests/heartbeat_tests.rs +48 -40
  145. package/sdk-core/crates/sdk-core/tests/integ_tests/metrics_tests.rs +327 -255
  146. package/sdk-core/crates/sdk-core/tests/integ_tests/pagination_tests.rs +50 -45
  147. package/sdk-core/crates/sdk-core/tests/integ_tests/polling_tests.rs +147 -126
  148. package/sdk-core/crates/sdk-core/tests/integ_tests/queries_tests.rs +103 -89
  149. package/sdk-core/crates/sdk-core/tests/integ_tests/update_tests.rs +609 -453
  150. package/sdk-core/crates/sdk-core/tests/integ_tests/visibility_tests.rs +80 -62
  151. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_heartbeat_tests.rs +360 -231
  152. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_tests.rs +248 -185
  153. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_versioning_tests.rs +52 -43
  154. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_client_tests.rs +180 -0
  155. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/activities.rs +428 -315
  156. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +82 -56
  157. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +56 -28
  158. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +364 -243
  159. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/client_interactions.rs +552 -0
  160. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +101 -42
  161. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +243 -147
  162. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/eager.rs +98 -28
  163. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +1475 -1036
  164. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +73 -41
  165. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +397 -238
  166. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/patches.rs +414 -189
  167. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/queries.rs +415 -0
  168. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/replay.rs +96 -36
  169. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/resets.rs +154 -137
  170. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/signals.rs +183 -105
  171. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +85 -38
  172. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/timers.rs +142 -40
  173. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +73 -54
  174. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests.rs +363 -226
  175. package/sdk-core/crates/sdk-core/tests/main.rs +17 -15
  176. package/sdk-core/crates/sdk-core/tests/manual_tests.rs +207 -152
  177. package/sdk-core/crates/sdk-core/tests/shared_tests/mod.rs +65 -34
  178. package/sdk-core/crates/sdk-core/tests/shared_tests/priority.rs +107 -84
  179. package/sdk-core/crates/sdk-core/tests/workflows_procmacro.rs +6 -0
  180. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.rs +26 -0
  181. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.stderr +5 -0
  182. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/basic_pass.rs +49 -0
  183. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/minimal_pass.rs +21 -0
  184. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.rs +26 -0
  185. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.stderr +5 -0
  186. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.rs +21 -0
  187. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.stderr +5 -0
  188. package/sdk-core/crates/sdk-core-c-bridge/Cargo.toml +7 -1
  189. package/sdk-core/crates/sdk-core-c-bridge/include/temporal-sdk-core-c-bridge.h +14 -14
  190. package/sdk-core/crates/sdk-core-c-bridge/src/client.rs +83 -74
  191. package/sdk-core/crates/sdk-core-c-bridge/src/metric.rs +9 -14
  192. package/sdk-core/crates/sdk-core-c-bridge/src/runtime.rs +1 -2
  193. package/sdk-core/crates/sdk-core-c-bridge/src/tests/context.rs +13 -13
  194. package/sdk-core/crates/sdk-core-c-bridge/src/tests/mod.rs +6 -6
  195. package/sdk-core/crates/sdk-core-c-bridge/src/tests/utils.rs +3 -4
  196. package/sdk-core/crates/sdk-core-c-bridge/src/worker.rs +62 -75
  197. package/sdk-core/rustfmt.toml +2 -1
  198. package/src/client.rs +205 -318
  199. package/src/metrics.rs +22 -30
  200. package/src/runtime.rs +4 -5
  201. package/src/worker.rs +16 -19
  202. package/ts/native.ts +1 -1
  203. package/sdk-core/crates/client/src/workflow_handle/mod.rs +0 -212
  204. package/sdk-core/crates/common/src/errors.rs +0 -85
  205. package/sdk-core/crates/common/tests/worker_task_types_test.rs +0 -129
  206. package/sdk-core/crates/sdk/src/activity_context.rs +0 -238
  207. package/sdk-core/crates/sdk/src/app_data.rs +0 -37
  208. package/sdk-core/crates/sdk-core/tests/integ_tests/activity_functions.rs +0 -5
  209. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +0 -61
@@ -1,5 +1,7 @@
1
1
  use crate::common::{CoreWfStarter, build_fake_sdk, init_core_and_create_wf};
2
- use std::time::Duration;
2
+ use futures_util::{StreamExt, stream::FuturesUnordered};
3
+ use std::{future::Future, pin::Pin, time::Duration};
4
+ use temporalio_client::WorkflowStartOptions;
3
5
  use temporalio_common::{
4
6
  prost_dur,
5
7
  protos::{
@@ -16,23 +18,41 @@ use temporalio_common::{
16
18
  },
17
19
  worker::WorkerTaskTypes,
18
20
  };
19
- use temporalio_sdk::{CancellableFuture, WfContext, WorkflowResult};
21
+ use temporalio_macros::{workflow, workflow_methods};
22
+ use temporalio_sdk::{CancellableFuture, WorkflowContext, WorkflowResult};
20
23
  use temporalio_sdk_core::test_help::{MockPollCfg, WorkerTestHelpers, drain_pollers_and_shutdown};
21
24
 
22
- pub(crate) async fn timer_wf(command_sink: WfContext) -> WorkflowResult<()> {
23
- command_sink.timer(Duration::from_secs(1)).await;
24
- Ok(().into())
25
+ #[workflow]
26
+ #[derive(Default)]
27
+ pub(crate) struct TimerWf;
28
+
29
+ #[workflow_methods]
30
+ impl TimerWf {
31
+ #[run(name = "timer_wf_new")]
32
+ pub(crate) async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
33
+ ctx.timer(Duration::from_secs(1)).await;
34
+ Ok(())
35
+ }
25
36
  }
26
37
 
27
38
  #[tokio::test]
28
39
  async fn timer_workflow_workflow_driver() {
29
40
  let wf_name = "timer_wf_new";
30
41
  let mut starter = CoreWfStarter::new(wf_name);
31
- starter.worker_config.task_types = WorkerTaskTypes::workflow_only();
42
+ starter.sdk_config.task_types = WorkerTaskTypes::workflow_only();
32
43
  let mut worker = starter.worker().await;
33
- worker.register_wf(wf_name.to_owned(), timer_wf);
44
+ worker.register_workflow::<TimerWf>();
34
45
 
35
- starter.start_with_worker(wf_name, &mut worker).await;
46
+ let task_queue = starter.get_task_queue().to_owned();
47
+ let workflow_id = starter.get_task_queue().to_owned();
48
+ worker
49
+ .submit_workflow(
50
+ TimerWf::run,
51
+ (),
52
+ WorkflowStartOptions::new(task_queue, workflow_id).build(),
53
+ )
54
+ .await
55
+ .unwrap();
36
56
  worker.run_until_done().await.unwrap();
37
57
  }
38
58
 
@@ -40,7 +60,7 @@ async fn timer_workflow_workflow_driver() {
40
60
  async fn timer_workflow_manual() {
41
61
  let mut starter = init_core_and_create_wf("timer_workflow").await;
42
62
  let core = starter.get_worker().await;
43
- starter.worker_config.task_types = WorkerTaskTypes::workflow_only();
63
+ starter.sdk_config.task_types = WorkerTaskTypes::workflow_only();
44
64
  let task = core.poll_workflow_activation().await.unwrap();
45
65
  core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
46
66
  task.run_id,
@@ -64,7 +84,7 @@ async fn timer_workflow_manual() {
64
84
  async fn timer_cancel_workflow() {
65
85
  let mut starter = init_core_and_create_wf("timer_cancel_workflow").await;
66
86
  let core = starter.get_worker().await;
67
- starter.worker_config.task_types = WorkerTaskTypes::workflow_only();
87
+ starter.sdk_config.task_types = WorkerTaskTypes::workflow_only();
68
88
  let task = core.poll_workflow_activation().await.unwrap();
69
89
  core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
70
90
  task.run_id,
@@ -112,28 +132,44 @@ async fn timer_immediate_cancel_workflow() {
112
132
  .unwrap();
113
133
  }
114
134
 
115
- async fn parallel_timer_wf(command_sink: WfContext) -> WorkflowResult<()> {
116
- let t1 = command_sink.timer(Duration::from_secs(1));
117
- let t2 = command_sink.timer(Duration::from_secs(1));
118
- let _ = tokio::join!(t1, t2);
119
- Ok(().into())
135
+ #[workflow]
136
+ #[derive(Default)]
137
+ struct ParallelTimerWf;
138
+
139
+ #[workflow_methods]
140
+ impl ParallelTimerWf {
141
+ #[run(name = "parallel_timers")]
142
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
143
+ let t1 = ctx.timer(Duration::from_secs(1));
144
+ let t2 = ctx.timer(Duration::from_secs(1));
145
+ let _ = temporalio_sdk::workflows::join!(t1, t2);
146
+ Ok(())
147
+ }
120
148
  }
121
149
 
122
150
  #[tokio::test]
123
151
  async fn parallel_timers() {
124
152
  let wf_name = "parallel_timers";
125
153
  let mut starter = CoreWfStarter::new(wf_name);
126
- starter.worker_config.task_types = WorkerTaskTypes::workflow_only();
154
+ starter.sdk_config.task_types = WorkerTaskTypes::workflow_only();
127
155
  let mut worker = starter.worker().await;
128
- worker.register_wf(wf_name.to_owned(), parallel_timer_wf);
156
+ worker.register_workflow::<ParallelTimerWf>();
129
157
 
130
158
  starter.start_with_worker(wf_name, &mut worker).await;
131
159
  worker.run_until_done().await.unwrap();
132
160
  }
133
161
 
134
- async fn happy_timer(ctx: WfContext) -> WorkflowResult<()> {
135
- ctx.timer(Duration::from_secs(5)).await;
136
- Ok(().into())
162
+ #[workflow]
163
+ #[derive(Default)]
164
+ struct HappyTimerWf;
165
+
166
+ #[workflow_methods]
167
+ impl HappyTimerWf {
168
+ #[run(name = DEFAULT_WORKFLOW_TYPE)]
169
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
170
+ ctx.timer(Duration::from_secs(5)).await;
171
+ Ok(())
172
+ }
137
173
  }
138
174
 
139
175
  #[tokio::test]
@@ -156,10 +192,23 @@ async fn test_fire_happy_path_inc() {
156
192
  });
157
193
 
158
194
  let mut worker = build_fake_sdk(mock_cfg);
159
- worker.register_wf(DEFAULT_WORKFLOW_TYPE, happy_timer);
195
+ worker.register_workflow::<HappyTimerWf>();
160
196
  worker.run().await.unwrap();
161
197
  }
162
198
 
199
+ #[workflow]
200
+ #[derive(Default)]
201
+ struct MismatchedTimerWf;
202
+
203
+ #[workflow_methods]
204
+ impl MismatchedTimerWf {
205
+ #[run(name = DEFAULT_WORKFLOW_TYPE)]
206
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
207
+ ctx.timer(Duration::from_secs(5)).await;
208
+ Ok(())
209
+ }
210
+ }
211
+
163
212
  #[tokio::test]
164
213
  async fn mismatched_timer_ids_errors() {
165
214
  let t = canned_histories::single_timer("badid");
@@ -171,20 +220,24 @@ async fn mismatched_timer_ids_errors() {
171
220
  if message.contains("Timer fired event did not have expected timer id 1"))
172
221
  });
173
222
  let mut worker = build_fake_sdk(mock_cfg);
174
- worker.register_wf(DEFAULT_WORKFLOW_TYPE, |ctx: WfContext| async move {
175
- ctx.timer(Duration::from_secs(5)).await;
176
- Ok(().into())
177
- });
223
+ worker.register_workflow::<MismatchedTimerWf>();
178
224
  worker.run().await.unwrap();
179
225
  }
180
226
 
181
- async fn cancel_timer(ctx: WfContext) -> WorkflowResult<()> {
182
- let cancel_timer_fut = ctx.timer(Duration::from_secs(500));
183
- ctx.timer(Duration::from_secs(5)).await;
184
- // Cancel the first timer after having waited on the second
185
- cancel_timer_fut.cancel(&ctx);
186
- cancel_timer_fut.await;
187
- Ok(().into())
227
+ #[workflow]
228
+ #[derive(Default)]
229
+ struct CancelTimerWf;
230
+
231
+ #[workflow_methods]
232
+ impl CancelTimerWf {
233
+ #[run(name = DEFAULT_WORKFLOW_TYPE)]
234
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
235
+ let cancel_timer_fut = ctx.timer(Duration::from_secs(500));
236
+ ctx.timer(Duration::from_secs(5)).await;
237
+ cancel_timer_fut.cancel();
238
+ cancel_timer_fut.await;
239
+ Ok(())
240
+ }
188
241
  }
189
242
 
190
243
  #[tokio::test]
@@ -209,10 +262,25 @@ async fn incremental_cancellation() {
209
262
  });
210
263
 
211
264
  let mut worker = build_fake_sdk(mock_cfg);
212
- worker.register_wf(DEFAULT_WORKFLOW_TYPE, cancel_timer);
265
+ worker.register_workflow::<CancelTimerWf>();
213
266
  worker.run().await.unwrap();
214
267
  }
215
268
 
269
+ #[workflow]
270
+ #[derive(Default)]
271
+ struct CancelBeforeSentWf;
272
+
273
+ #[workflow_methods]
274
+ impl CancelBeforeSentWf {
275
+ #[run(name = DEFAULT_WORKFLOW_TYPE)]
276
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
277
+ let cancel_timer_fut = ctx.timer(Duration::from_secs(500));
278
+ cancel_timer_fut.cancel();
279
+ cancel_timer_fut.await;
280
+ Ok(())
281
+ }
282
+ }
283
+
216
284
  #[tokio::test]
217
285
  async fn cancel_before_sent_to_server() {
218
286
  let mut t = TestHistoryBuilder::default();
@@ -230,12 +298,46 @@ async fn cancel_before_sent_to_server() {
230
298
  });
231
299
  });
232
300
  let mut worker = build_fake_sdk(mock_cfg);
233
- worker.register_wf(DEFAULT_WORKFLOW_TYPE, |ctx: WfContext| async move {
234
- let cancel_timer_fut = ctx.timer(Duration::from_secs(500));
235
- // Immediately cancel the timer
236
- cancel_timer_fut.cancel(&ctx);
237
- cancel_timer_fut.await;
238
- Ok(().into())
239
- });
301
+ worker.register_workflow::<CancelBeforeSentWf>();
302
+ worker.run().await.unwrap();
303
+ }
304
+
305
+ #[workflow]
306
+ #[derive(Default)]
307
+ struct WaitConditionWakerWf {
308
+ done: bool,
309
+ }
310
+
311
+ #[workflow_methods]
312
+ impl WaitConditionWakerWf {
313
+ #[run(name = DEFAULT_WORKFLOW_TYPE)]
314
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
315
+ let mut futs: FuturesUnordered<Pin<Box<dyn Future<Output = ()>>>> = FuturesUnordered::new();
316
+
317
+ // Future 1: await timer, then set flag via state_mut
318
+ let ctx1 = ctx.clone();
319
+ futs.push(Box::pin(async move {
320
+ ctx1.timer(Duration::from_millis(500)).await;
321
+ ctx1.state_mut(|s| s.done = true);
322
+ }));
323
+
324
+ // Future 2: wait_condition on the flag (waker-dependent inside FuturesUnordered)
325
+ let ctx2 = ctx.clone();
326
+ futs.push(Box::pin(async move {
327
+ ctx2.wait_condition(|s| s.done).await;
328
+ }));
329
+
330
+ // Drive both to completion
331
+ while futs.next().await.is_some() {}
332
+ Ok(())
333
+ }
334
+ }
335
+
336
+ #[tokio::test]
337
+ async fn wait_condition_waker_in_futures_unordered() {
338
+ let t = canned_histories::single_timer_wf_completes("1");
339
+ let mock_cfg = MockPollCfg::from_hist_builder(t);
340
+ let mut worker = build_fake_sdk(mock_cfg);
341
+ worker.register_workflow::<WaitConditionWakerWf>();
240
342
  worker.run().await.unwrap();
241
343
  }
@@ -2,8 +2,7 @@ use crate::common::{CoreWfStarter, SEARCH_ATTR_INT, SEARCH_ATTR_TXT, build_fake_
2
2
  use assert_matches::assert_matches;
3
3
  use std::{collections::HashMap, time::Duration};
4
4
  use temporalio_client::{
5
- GetWorkflowResultOptions, WfClientExt, WorkflowClientTrait, WorkflowExecutionResult,
6
- WorkflowOptions,
5
+ UntypedWorkflow, WorkflowDescribeOptions, WorkflowGetResultOptions, WorkflowStartOptions,
7
6
  };
8
7
  use temporalio_common::{
9
8
  protos::{
@@ -17,28 +16,36 @@ use temporalio_common::{
17
16
  },
18
17
  worker::WorkerTaskTypes,
19
18
  };
20
- use temporalio_sdk::{WfContext, WfExitValue, WorkflowResult};
19
+ use temporalio_macros::{workflow, workflow_methods};
20
+ use temporalio_sdk::{WorkflowContext, WorkflowResult, WorkflowTermination};
21
21
  use temporalio_sdk_core::test_help::MockPollCfg;
22
22
  use uuid::Uuid;
23
23
 
24
- async fn search_attr_updater(ctx: WfContext) -> WorkflowResult<()> {
25
- let mut int_val = ctx
26
- .search_attributes()
27
- .indexed_fields
28
- .get(SEARCH_ATTR_INT)
29
- .cloned()
30
- .unwrap_or_default();
31
- let orig_val = int_val.data[0];
32
- int_val.data[0] += 1;
33
- ctx.upsert_search_attributes([
34
- (SEARCH_ATTR_TXT.to_string(), "goodbye".as_json_payload()?),
35
- (SEARCH_ATTR_INT.to_string(), int_val),
36
- ]);
37
- // 49 is ascii 1
38
- if orig_val == 49 {
39
- Ok(WfExitValue::ContinueAsNew(Box::default()))
40
- } else {
41
- Ok(().into())
24
+ #[workflow]
25
+ #[derive(Default)]
26
+ struct SearchAttrUpdater;
27
+
28
+ #[workflow_methods]
29
+ impl SearchAttrUpdater {
30
+ #[run(name = "sends_upsert_search_attrs")]
31
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
32
+ let mut int_val = ctx
33
+ .search_attributes()
34
+ .indexed_fields
35
+ .get(SEARCH_ATTR_INT)
36
+ .cloned()
37
+ .unwrap_or_default();
38
+ let orig_val = int_val.data[0];
39
+ int_val.data[0] += 1;
40
+ ctx.upsert_search_attributes([
41
+ (SEARCH_ATTR_TXT.to_string(), "goodbye".as_json_payload()?),
42
+ (SEARCH_ATTR_INT.to_string(), int_val),
43
+ ]);
44
+ if orig_val == 49 {
45
+ Err(WorkflowTermination::continue_as_new(Default::default()))
46
+ } else {
47
+ Ok(())
48
+ }
42
49
  }
43
50
  }
44
51
 
@@ -47,26 +54,25 @@ async fn sends_upsert() {
47
54
  let wf_name = "sends_upsert_search_attrs";
48
55
  let wf_id = Uuid::new_v4();
49
56
  let mut starter = CoreWfStarter::new(wf_name);
50
- starter.worker_config.task_types = WorkerTaskTypes::workflow_only();
57
+ starter.sdk_config.task_types = WorkerTaskTypes::workflow_only();
51
58
  let mut worker = starter.worker().await;
52
59
 
53
- worker.register_wf(wf_name, search_attr_updater);
60
+ worker.register_workflow::<SearchAttrUpdater>();
61
+ let task_queue = starter.get_task_queue().to_owned();
54
62
  worker
55
63
  .submit_wf(
56
- wf_id.to_string(),
57
64
  wf_name,
58
65
  vec![],
59
- WorkflowOptions {
60
- search_attributes: Some(HashMap::from([
66
+ WorkflowStartOptions::new(task_queue, wf_id.to_string())
67
+ .search_attributes(HashMap::from([
61
68
  (
62
69
  SEARCH_ATTR_TXT.to_string(),
63
70
  "hello".as_json_payload().unwrap(),
64
71
  ),
65
72
  (SEARCH_ATTR_INT.to_string(), 1.as_json_payload().unwrap()),
66
- ])),
67
- execution_timeout: Some(Duration::from_secs(4)),
68
- ..Default::default()
69
- },
73
+ ]))
74
+ .execution_timeout(Duration::from_secs(4))
75
+ .build(),
70
76
  )
71
77
  .await
72
78
  .unwrap();
@@ -74,9 +80,11 @@ async fn sends_upsert() {
74
80
 
75
81
  let client = starter.get_client().await;
76
82
  let search_attrs = client
77
- .describe_workflow_execution(wf_id.to_string(), None)
83
+ .get_workflow_handle::<UntypedWorkflow>(wf_id.to_string())
84
+ .describe(WorkflowDescribeOptions::default())
78
85
  .await
79
86
  .unwrap()
87
+ .raw_description
80
88
  .workflow_execution_info
81
89
  .unwrap()
82
90
  .search_attributes
@@ -92,12 +100,41 @@ async fn sends_upsert() {
92
100
  String::from_json_payload(txt_attr_payload).unwrap()
93
101
  );
94
102
  assert_eq!(3, usize::from_json_payload(int_attr_payload).unwrap());
95
- let handle = client.get_untyped_workflow_handle(wf_id.to_string(), "");
96
- let res = handle
97
- .get_workflow_result(GetWorkflowResultOptions::default())
103
+ let handle = client.get_workflow_handle::<UntypedWorkflow>(wf_id.to_string());
104
+ handle
105
+ .get_result(WorkflowGetResultOptions::default())
98
106
  .await
99
107
  .unwrap();
100
- assert_matches!(res, WorkflowExecutionResult::Succeeded(_));
108
+ }
109
+
110
+ #[workflow]
111
+ #[derive(Default)]
112
+ struct UpsertTestWf;
113
+
114
+ #[workflow_methods]
115
+ impl UpsertTestWf {
116
+ #[run(name = DEFAULT_WORKFLOW_TYPE)]
117
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
118
+ const K1: &str = "foo";
119
+ const K2: &str = "bar";
120
+ ctx.upsert_search_attributes([
121
+ (
122
+ String::from(K1),
123
+ Payload {
124
+ data: vec![0x01],
125
+ ..Default::default()
126
+ },
127
+ ),
128
+ (
129
+ String::from(K2),
130
+ Payload {
131
+ data: vec![0x02],
132
+ ..Default::default()
133
+ },
134
+ ),
135
+ ]);
136
+ Ok(())
137
+ }
101
138
  }
102
139
 
103
140
  #[tokio::test]
@@ -129,24 +166,6 @@ async fn upsert_search_attrs_from_workflow() {
129
166
  });
130
167
 
131
168
  let mut worker = build_fake_sdk(mock_cfg);
132
- worker.register_wf(DEFAULT_WORKFLOW_TYPE, move |ctx: WfContext| async move {
133
- ctx.upsert_search_attributes([
134
- (
135
- String::from(k1),
136
- Payload {
137
- data: vec![0x01],
138
- ..Default::default()
139
- },
140
- ),
141
- (
142
- String::from(k2),
143
- Payload {
144
- data: vec![0x02],
145
- ..Default::default()
146
- },
147
- ),
148
- ]);
149
- Ok(().into())
150
- });
169
+ worker.register_workflow::<UpsertTestWf>();
151
170
  worker.run().await.unwrap();
152
171
  }