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