@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
@@ -12,8 +12,9 @@ mod shared_tests;
12
12
 
13
13
  #[cfg(test)]
14
14
  mod integ_tests {
15
- mod activity_functions;
15
+ mod async_activity_client_tests;
16
16
  mod client_tests;
17
+ mod data_converter_tests;
17
18
  mod ephemeral_server_tests;
18
19
  mod heartbeat_tests;
19
20
  mod metrics_tests;
@@ -25,6 +26,7 @@ mod integ_tests {
25
26
  mod worker_heartbeat_tests;
26
27
  mod worker_tests;
27
28
  mod worker_versioning_tests;
29
+ mod workflow_client_tests;
28
30
  mod workflow_tests;
29
31
 
30
32
  use crate::common::{
@@ -32,16 +34,19 @@ mod integ_tests {
32
34
  get_integ_telem_options, rand_6_chars,
33
35
  };
34
36
  use std::time::Duration;
35
- use temporalio_client::{NamespacedClient, WorkflowService};
37
+ use temporalio_client::{
38
+ Connection, NamespacedClient,
39
+ grpc::{OperatorService, WorkflowService},
40
+ };
36
41
  use temporalio_common::{
37
42
  protos::temporal::api::{
38
43
  nexus::v1::{EndpointSpec, EndpointTarget, endpoint_target},
39
44
  operatorservice::v1::CreateNexusEndpointRequest,
40
45
  workflowservice::v1::ListNamespacesRequest,
41
46
  },
42
- worker::{WorkerConfig, WorkerTaskTypes, WorkerVersioningStrategy},
47
+ worker::WorkerTaskTypes,
43
48
  };
44
- use temporalio_sdk_core::{CoreRuntime, init_worker};
49
+ use temporalio_sdk_core::{CoreRuntime, WorkerConfig, WorkerVersioningStrategy, init_worker};
45
50
  use tonic::IntoRequest;
46
51
 
47
52
  // Create a worker like a bridge would (unwraps aside)
@@ -52,10 +57,7 @@ mod integ_tests {
52
57
  let runtime =
53
58
  CoreRuntime::new_assume_tokio(get_integ_runtime_options(get_integ_telem_options()))
54
59
  .unwrap();
55
- let mut retrying_client = opts
56
- .connect_no_namespace(runtime.telemetry().get_temporal_metric_meter())
57
- .await
58
- .unwrap();
60
+ let mut connection = Connection::connect(opts).await.unwrap();
59
61
 
60
62
  let _worker = init_worker(
61
63
  &runtime,
@@ -68,13 +70,12 @@ mod integ_tests {
68
70
  })
69
71
  .build()
70
72
  .unwrap(),
71
- // clone the client if you intend to use it later. Strip off the retry wrapper since
72
- // worker will assert its own
73
- retrying_client.clone(),
73
+ // clone the connection if you intend to use it later
74
+ connection.clone(),
74
75
  );
75
76
 
76
- // Do things with worker or client
77
- let _ = retrying_client
77
+ // Do things with worker or connection
78
+ let _ = connection
78
79
  .list_namespaces(ListNamespacesRequest::default().into_request())
79
80
  .await;
80
81
  }
@@ -82,8 +83,9 @@ mod integ_tests {
82
83
  pub(crate) async fn mk_nexus_endpoint(starter: &mut CoreWfStarter) -> String {
83
84
  let client = starter.get_client().await;
84
85
  let endpoint = format!("mycoolendpoint-{}", rand_6_chars());
85
- let mut op_client = client.get_client().inner().operator_svc();
86
- op_client
86
+ client
87
+ .connection()
88
+ .clone()
87
89
  .create_nexus_endpoint(
88
90
  CreateNexusEndpointRequest {
89
91
  spec: Some(EndpointSpec {
@@ -17,20 +17,114 @@ use rand::{Rng, SeedableRng};
17
17
  use std::{
18
18
  mem,
19
19
  net::SocketAddr,
20
+ sync::Arc,
20
21
  time::{Duration, Instant},
21
22
  };
22
23
  use temporalio_client::{
23
- GetWorkflowResultOptions, WfClientExt, WorkflowClientTrait, WorkflowOptions,
24
+ NamespacedClient, UntypedSignal, UntypedWorkflow, WorkflowExecutionInfo,
25
+ WorkflowGetResultOptions, WorkflowSignalOptions, WorkflowStartOptions,
24
26
  };
25
27
  use temporalio_common::{
26
- protos::coresdk::AsJsonPayloadExt,
27
- telemetry::PrometheusExporterOptions,
28
- worker::{PollerBehavior, WorkerTaskTypes},
28
+ data_converters::RawValue, telemetry::PrometheusExporterOptions, worker::WorkerTaskTypes,
29
29
  };
30
- use temporalio_sdk::{ActContext, ActivityOptions, WfContext};
31
- use temporalio_sdk_core::CoreRuntime;
30
+ use temporalio_macros::{activities, workflow, workflow_methods};
31
+ use temporalio_sdk::{
32
+ ActivityOptions, SyncWorkflowContext, WorkflowContext, WorkflowResult,
33
+ activities::{ActivityContext, ActivityError},
34
+ };
35
+ use temporalio_sdk_core::{CoreRuntime, PollerBehavior, TunerHolder};
32
36
  use tracing::info;
33
37
 
38
+ struct JitteryEchoActivities;
39
+ #[activities]
40
+ impl JitteryEchoActivities {
41
+ #[activity]
42
+ async fn echo(_ctx: ActivityContext, echo: String) -> Result<String, ActivityError> {
43
+ // Add some jitter to completions
44
+ let rand_millis = rand::rng().random_range(0..500);
45
+ tokio::time::sleep(Duration::from_millis(rand_millis)).await;
46
+ Ok(echo)
47
+ }
48
+ }
49
+
50
+ #[workflow]
51
+ #[derive(Default)]
52
+ struct PollerLoadSpikyWf;
53
+
54
+ #[workflow_methods]
55
+ impl PollerLoadSpikyWf {
56
+ #[run(name = "poller_load")]
57
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
58
+ for _ in 0..5 {
59
+ let _ = ctx
60
+ .start_activity(
61
+ JitteryEchoActivities::echo,
62
+ "hi!".to_string(),
63
+ ActivityOptions {
64
+ start_to_close_timeout: Some(Duration::from_secs(5)),
65
+ ..Default::default()
66
+ },
67
+ )
68
+ .await;
69
+ }
70
+
71
+ Ok(())
72
+ }
73
+
74
+ #[signal(name = "signame")]
75
+ fn drain_signal(&mut self, _ctx: &mut SyncWorkflowContext<Self>, _: ()) {}
76
+ }
77
+
78
+ #[workflow]
79
+ #[derive(Default)]
80
+ struct PollerLoadSustainedWf;
81
+
82
+ #[workflow_methods]
83
+ impl PollerLoadSustainedWf {
84
+ #[run(name = "poller_load")]
85
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
86
+ let rs = ctx.random_seed();
87
+ let mut rand = rand::rngs::SmallRng::seed_from_u64(rs);
88
+ for _ in 0..100 {
89
+ let jitterms = rand.random_range(1000..3000);
90
+ ctx.timer(Duration::from_millis(jitterms)).await;
91
+ }
92
+
93
+ Ok(())
94
+ }
95
+
96
+ #[signal(name = "signame")]
97
+ fn drain_signal(&mut self, _ctx: &mut SyncWorkflowContext<Self>, _: ()) {}
98
+ }
99
+
100
+ #[workflow]
101
+ #[derive(Default)]
102
+ struct PollerLoadSpikeThenSustainedWf;
103
+
104
+ #[workflow_methods]
105
+ impl PollerLoadSpikeThenSustainedWf {
106
+ #[run(name = "poller_load")]
107
+ async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<()> {
108
+ for _ in 0..5 {
109
+ let _ = ctx
110
+ .start_activity(
111
+ JitteryEchoActivities::echo,
112
+ "hi!".to_string(),
113
+ ActivityOptions {
114
+ start_to_close_timeout: Some(Duration::from_secs(5)),
115
+ ..Default::default()
116
+ },
117
+ )
118
+ .await;
119
+ }
120
+
121
+ Ok(())
122
+ }
123
+
124
+ #[signal(name = "signame")]
125
+ fn drain_signal(&mut self, _ctx: &mut SyncWorkflowContext<Self>, _: ()) {}
126
+ }
127
+
34
128
  #[tokio::test]
35
129
  async fn poller_load_spiky() {
36
130
  const SIGNAME: &str = "signame";
@@ -48,50 +142,25 @@ async fn poller_load_spiky() {
48
142
  };
49
143
  let rt = CoreRuntime::new_assume_tokio(get_integ_runtime_options(telemopts)).unwrap();
50
144
  let mut starter = CoreWfStarter::new_with_runtime("poller_load", rt);
51
- starter.worker_config.max_cached_workflows = 5000;
52
- starter.worker_config.max_outstanding_workflow_tasks = Some(1000);
53
- starter.worker_config.max_outstanding_activities = Some(1000);
54
- starter.worker_config.workflow_task_poller_behavior = PollerBehavior::Autoscaling {
145
+ starter.sdk_config.max_cached_workflows = 5000;
146
+ starter.sdk_config.tuner = Arc::new(TunerHolder::fixed_size(1000, 1000, 100, 100));
147
+ starter.sdk_config.workflow_task_poller_behavior = PollerBehavior::Autoscaling {
55
148
  minimum: 1,
56
149
  maximum: 200,
57
150
  initial: 5,
58
151
  };
59
- starter.worker_config.activity_task_poller_behavior = PollerBehavior::Autoscaling {
152
+ starter.sdk_config.activity_task_poller_behavior = PollerBehavior::Autoscaling {
60
153
  minimum: 1,
61
154
  maximum: 200,
62
155
  initial: 5,
63
156
  };
64
157
  let mut worker = starter.worker().await;
65
158
  let submitter = worker.get_submitter_handle();
66
- worker.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
67
- let sigchan = ctx.make_signal_channel(SIGNAME).map(Ok);
68
- let drained_fut = sigchan.forward(sink::drain());
69
-
70
- let real_stuff = async move {
71
- for _ in 0..5 {
72
- ctx.activity(ActivityOptions {
73
- activity_type: "echo".to_string(),
74
- start_to_close_timeout: Some(Duration::from_secs(5)),
75
- input: "hi!".as_json_payload().expect("serializes fine"),
76
- ..Default::default()
77
- })
78
- .await;
79
- }
80
- };
81
- tokio::select! {
82
- _ = drained_fut => {}
83
- _ = real_stuff => {}
84
- }
85
159
 
86
- Ok(().into())
87
- });
88
- worker.register_activity("echo", |_: ActContext, echo: String| async move {
89
- // Add some jitter to completions
90
- let rand_millis = rand::rng().random_range(0..500);
91
- tokio::time::sleep(Duration::from_millis(rand_millis)).await;
92
- Ok(echo)
93
- });
160
+ worker.register_activities(JitteryEchoActivities);
161
+ worker.register_workflow::<PollerLoadSpikyWf>();
94
162
  let client = starter.get_client().await;
163
+ let tq = starter.get_task_queue().to_owned();
95
164
 
96
165
  info!("Prom bound to {:?}", addr);
97
166
 
@@ -101,17 +170,23 @@ async fn poller_load_spiky() {
101
170
  let wfid = format!("{wf_name}_{i}-{}", rand_6_chars());
102
171
  let rid = worker
103
172
  .submit_wf(
104
- wfid.clone(),
105
173
  wf_name.to_owned(),
106
174
  vec![],
107
- WorkflowOptions {
108
- execution_timeout: Some(Duration::from_secs(120)),
109
- ..Default::default()
110
- },
175
+ WorkflowStartOptions::new(tq.clone(), wfid.clone())
176
+ .execution_timeout(Duration::from_secs(120))
177
+ .build(),
111
178
  )
112
179
  .await
113
180
  .unwrap();
114
- workflow_handles.push(client.get_untyped_workflow_handle(wfid, rid));
181
+ workflow_handles.push(
182
+ WorkflowExecutionInfo {
183
+ namespace: client.namespace(),
184
+ workflow_id: wfid,
185
+ run_id: Some(rid),
186
+ first_execution_run_id: None,
187
+ }
188
+ .bind_untyped(client.clone()),
189
+ );
115
190
  }
116
191
  info!("Done starting workflows");
117
192
  let start_processing = Instant::now();
@@ -120,9 +195,7 @@ async fn poller_load_spiky() {
120
195
  let all_workflows_are_done = async {
121
196
  stream::iter(mem::take(&mut workflow_handles))
122
197
  .for_each_concurrent(25, |handle| async move {
123
- let _ = handle
124
- .get_workflow_result(GetWorkflowResultOptions::default())
125
- .await;
198
+ let _ = handle.get_result(WorkflowGetResultOptions::default()).await;
126
199
  })
127
200
  .await;
128
201
  info!("Initial load ran for {:?}", start_processing.elapsed());
@@ -135,23 +208,27 @@ async fn poller_load_spiky() {
135
208
  let wfid = format!("{wf_name}_2_{i}-{}", rand_6_chars());
136
209
  let rid = submitter
137
210
  .submit_wf(
138
- wfid.clone(),
139
211
  wf_name.to_owned(),
140
212
  vec![],
141
- WorkflowOptions {
142
- execution_timeout: Some(Duration::from_secs(120)),
143
- ..Default::default()
144
- },
213
+ WorkflowStartOptions::new(tq.clone(), wfid.clone())
214
+ .execution_timeout(Duration::from_secs(120))
215
+ .build(),
145
216
  )
146
217
  .await
147
218
  .unwrap();
148
- workflow_handles.push(client.get_untyped_workflow_handle(wfid, rid));
219
+ workflow_handles.push(
220
+ WorkflowExecutionInfo {
221
+ namespace: client.namespace(),
222
+ workflow_id: wfid,
223
+ run_id: Some(rid),
224
+ first_execution_run_id: None,
225
+ }
226
+ .bind_untyped(client.clone()),
227
+ );
149
228
  }
150
229
  stream::iter(workflow_handles)
151
230
  .for_each_concurrent(25, |handle| async move {
152
- let _ = handle
153
- .get_workflow_result(GetWorkflowResultOptions::default())
154
- .await;
231
+ let _ = handle.get_result(WorkflowGetResultOptions::default()).await;
155
232
  })
156
233
  .await;
157
234
  info!("Second load ran for {:?}", start_processing.elapsed());
@@ -164,13 +241,17 @@ async fn poller_load_spiky() {
164
241
  loop {
165
242
  let sends: FuturesUnordered<_> = (0..num_workflows)
166
243
  .map(|i| {
167
- client.signal_workflow_execution(
168
- format!("{wf_name}_{i}"),
169
- "".to_string(),
170
- SIGNAME.to_string(),
171
- None,
172
- None,
173
- )
244
+ let handle =
245
+ client.get_workflow_handle::<UntypedWorkflow>(format!("{wf_name}_{i}"));
246
+ async move {
247
+ handle
248
+ .signal(
249
+ UntypedSignal::new(SIGNAME),
250
+ RawValue::empty(),
251
+ WorkflowSignalOptions::default(),
252
+ )
253
+ .await
254
+ }
174
255
  })
175
256
  .collect();
176
257
  sends
@@ -189,7 +270,6 @@ async fn poller_load_spiky() {
189
270
 
190
271
  #[tokio::test]
191
272
  async fn poller_load_sustained() {
192
- const SIGNAME: &str = "signame";
193
273
  let num_workflows = 150;
194
274
  let wf_name = "poller_load";
195
275
  let (telemopts, addr, _aborter) =
@@ -204,35 +284,18 @@ async fn poller_load_sustained() {
204
284
  };
205
285
  let rt = CoreRuntime::new_assume_tokio(get_integ_runtime_options(telemopts)).unwrap();
206
286
  let mut starter = CoreWfStarter::new_with_runtime("poller_load", rt);
207
- starter.worker_config.max_cached_workflows = 5000;
208
- starter.worker_config.max_outstanding_workflow_tasks = Some(1000);
209
- starter.worker_config.workflow_task_poller_behavior = PollerBehavior::Autoscaling {
287
+ starter.sdk_config.max_cached_workflows = 5000;
288
+ starter.sdk_config.tuner = Arc::new(TunerHolder::fixed_size(1000, 100, 100, 100));
289
+ starter.sdk_config.workflow_task_poller_behavior = PollerBehavior::Autoscaling {
210
290
  minimum: 1,
211
291
  maximum: 200,
212
292
  initial: 5,
213
293
  };
214
- starter.worker_config.task_types = WorkerTaskTypes::workflow_only();
294
+ starter.sdk_config.task_types = WorkerTaskTypes::workflow_only();
215
295
  let mut worker = starter.worker().await;
216
- worker.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
217
- let sigchan = ctx.make_signal_channel(SIGNAME).map(Ok);
218
- let drained_fut = sigchan.forward(sink::drain());
219
-
220
- let real_stuff = async move {
221
- let rs = ctx.random_seed();
222
- let mut rand = rand::rngs::SmallRng::seed_from_u64(rs);
223
- for _ in 0..100 {
224
- let jitterms = rand.random_range(1000..3000);
225
- ctx.timer(Duration::from_millis(jitterms)).await;
226
- }
227
- };
228
- tokio::select! {
229
- _ = drained_fut => {}
230
- _ = real_stuff => {}
231
- }
232
-
233
- Ok(().into())
234
- });
296
+ worker.register_workflow::<PollerLoadSustainedWf>();
235
297
  let client = starter.get_client().await;
298
+ let tq = starter.get_task_queue().to_owned();
236
299
 
237
300
  info!("Prom bound to {:?}", addr);
238
301
 
@@ -242,17 +305,23 @@ async fn poller_load_sustained() {
242
305
  let wfid = format!("{wf_name}_{i}-{}", rand_6_chars());
243
306
  let rid = worker
244
307
  .submit_wf(
245
- wfid.clone(),
246
308
  wf_name.to_owned(),
247
309
  vec![],
248
- WorkflowOptions {
249
- execution_timeout: Some(Duration::from_secs(800)),
250
- ..Default::default()
251
- },
310
+ WorkflowStartOptions::new(tq.clone(), wfid.clone())
311
+ .execution_timeout(Duration::from_secs(800))
312
+ .build(),
252
313
  )
253
314
  .await
254
315
  .unwrap();
255
- workflow_handles.push(client.get_untyped_workflow_handle(wfid, rid));
316
+ workflow_handles.push(
317
+ WorkflowExecutionInfo {
318
+ namespace: client.namespace(),
319
+ workflow_id: wfid,
320
+ run_id: Some(rid),
321
+ first_execution_run_id: None,
322
+ }
323
+ .bind_untyped(client.clone()),
324
+ );
256
325
  }
257
326
  info!("Done starting workflows");
258
327
  let start_processing = Instant::now();
@@ -260,9 +329,7 @@ async fn poller_load_sustained() {
260
329
  let all_workflows_are_done = async {
261
330
  stream::iter(mem::take(&mut workflow_handles))
262
331
  .for_each_concurrent(25, |handle| async move {
263
- let _ = handle
264
- .get_workflow_result(GetWorkflowResultOptions::default())
265
- .await;
332
+ let _ = handle.get_result(WorkflowGetResultOptions::default()).await;
266
333
  })
267
334
  .await;
268
335
  info!("Initial load ran for {:?}", start_processing.elapsed());
@@ -292,49 +359,25 @@ async fn poller_load_spike_then_sustained() {
292
359
  };
293
360
  let rt = CoreRuntime::new_assume_tokio(get_integ_runtime_options(telemopts)).unwrap();
294
361
  let mut starter = CoreWfStarter::new_with_runtime("poller_load", rt);
295
- starter.worker_config.max_cached_workflows = 5000;
296
- starter.worker_config.max_outstanding_workflow_tasks = Some(1000);
297
- starter.worker_config.workflow_task_poller_behavior = PollerBehavior::Autoscaling {
362
+ starter.sdk_config.max_cached_workflows = 5000;
363
+ starter.sdk_config.tuner = Arc::new(TunerHolder::fixed_size(1000, 100, 100, 100));
364
+ starter.sdk_config.workflow_task_poller_behavior = PollerBehavior::Autoscaling {
298
365
  minimum: 1,
299
366
  maximum: 200,
300
367
  initial: 5,
301
368
  };
302
- starter.worker_config.activity_task_poller_behavior = PollerBehavior::Autoscaling {
369
+ starter.sdk_config.activity_task_poller_behavior = PollerBehavior::Autoscaling {
303
370
  minimum: 1,
304
371
  maximum: 200,
305
372
  initial: 5,
306
373
  };
307
374
  let mut worker = starter.worker().await;
308
375
  let submitter = worker.get_submitter_handle();
309
- worker.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
310
- let sigchan = ctx.make_signal_channel(SIGNAME).map(Ok);
311
- let drained_fut = sigchan.forward(sink::drain());
312
-
313
- let real_stuff = async move {
314
- for _ in 0..5 {
315
- ctx.activity(ActivityOptions {
316
- activity_type: "echo".to_string(),
317
- start_to_close_timeout: Some(Duration::from_secs(5)),
318
- input: "hi!".as_json_payload().expect("serializes fine"),
319
- ..Default::default()
320
- })
321
- .await;
322
- }
323
- };
324
- tokio::select! {
325
- _ = drained_fut => {}
326
- _ = real_stuff => {}
327
- }
328
376
 
329
- Ok(().into())
330
- });
331
- worker.register_activity("echo", |_: ActContext, echo: String| async move {
332
- // Add some jitter to completions
333
- let rand_millis = rand::rng().random_range(0..500);
334
- tokio::time::sleep(Duration::from_millis(rand_millis)).await;
335
- Ok(echo)
336
- });
377
+ worker.register_activities(JitteryEchoActivities);
378
+ worker.register_workflow::<PollerLoadSpikeThenSustainedWf>();
337
379
  let client = starter.get_client().await;
380
+ let tq = starter.get_task_queue().to_owned();
338
381
 
339
382
  info!("Prom bound to {:?}", addr);
340
383
 
@@ -344,17 +387,23 @@ async fn poller_load_spike_then_sustained() {
344
387
  let wfid = format!("{wf_name}_{i}-{}", rand_6_chars());
345
388
  let rid = worker
346
389
  .submit_wf(
347
- wfid.clone(),
348
390
  wf_name.to_owned(),
349
391
  vec![],
350
- WorkflowOptions {
351
- execution_timeout: Some(Duration::from_secs(100)),
352
- ..Default::default()
353
- },
392
+ WorkflowStartOptions::new(tq.clone(), wfid.clone())
393
+ .execution_timeout(Duration::from_secs(100))
394
+ .build(),
354
395
  )
355
396
  .await
356
397
  .unwrap();
357
- workflow_handles.push(client.get_untyped_workflow_handle(wfid, rid));
398
+ workflow_handles.push(
399
+ WorkflowExecutionInfo {
400
+ namespace: client.namespace(),
401
+ workflow_id: wfid,
402
+ run_id: Some(rid),
403
+ first_execution_run_id: None,
404
+ }
405
+ .bind_untyped(client.clone()),
406
+ );
358
407
  }
359
408
  info!("Done starting workflows");
360
409
  let start_processing = Instant::now();
@@ -363,9 +412,7 @@ async fn poller_load_spike_then_sustained() {
363
412
  let all_workflows_are_done = async {
364
413
  stream::iter(mem::take(&mut workflow_handles))
365
414
  .for_each_concurrent(25, |handle| async move {
366
- let _ = handle
367
- .get_workflow_result(GetWorkflowResultOptions::default())
368
- .await;
415
+ let _ = handle.get_result(WorkflowGetResultOptions::default()).await;
369
416
  })
370
417
  .await;
371
418
  info!("Initial load ran for {:?}", start_processing.elapsed());
@@ -377,24 +424,28 @@ async fn poller_load_spike_then_sustained() {
377
424
  let wfid = format!("{wf_name}_2_{i}-{}", rand_6_chars());
378
425
  let rid = submitter
379
426
  .submit_wf(
380
- wfid.clone(),
381
427
  wf_name.to_owned(),
382
428
  vec![],
383
- WorkflowOptions {
384
- execution_timeout: Some(Duration::from_secs(100)),
385
- ..Default::default()
386
- },
429
+ WorkflowStartOptions::new(tq.clone(), wfid.clone())
430
+ .execution_timeout(Duration::from_secs(100))
431
+ .build(),
387
432
  )
388
433
  .await
389
434
  .unwrap();
390
- workflow_handles.push(client.get_untyped_workflow_handle(wfid, rid));
435
+ workflow_handles.push(
436
+ WorkflowExecutionInfo {
437
+ namespace: client.namespace(),
438
+ workflow_id: wfid,
439
+ run_id: Some(rid),
440
+ first_execution_run_id: None,
441
+ }
442
+ .bind_untyped(client.clone()),
443
+ );
391
444
  tokio::time::sleep(Duration::from_secs(1)).await;
392
445
  }
393
446
  stream::iter(workflow_handles)
394
447
  .for_each_concurrent(25, |handle| async move {
395
- let _ = handle
396
- .get_workflow_result(GetWorkflowResultOptions::default())
397
- .await;
448
+ let _ = handle.get_result(WorkflowGetResultOptions::default()).await;
398
449
  })
399
450
  .await;
400
451
  info!("Second load ran for {:?}", start_processing.elapsed());
@@ -407,13 +458,17 @@ async fn poller_load_spike_then_sustained() {
407
458
  loop {
408
459
  let sends: FuturesUnordered<_> = (0..num_workflows)
409
460
  .map(|i| {
410
- client.signal_workflow_execution(
411
- format!("{wf_name}_{i}"),
412
- "".to_string(),
413
- SIGNAME.to_string(),
414
- None,
415
- None,
416
- )
461
+ let handle =
462
+ client.get_workflow_handle::<UntypedWorkflow>(format!("{wf_name}_{i}"));
463
+ async move {
464
+ handle
465
+ .signal(
466
+ UntypedSignal::new(SIGNAME),
467
+ RawValue::empty(),
468
+ WorkflowSignalOptions::default(),
469
+ )
470
+ .await
471
+ }
417
472
  })
418
473
  .collect();
419
474
  sends