@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
@@ -0,0 +1,230 @@
1
+ use crate::common::CoreWfStarter;
2
+ use rstest::rstest;
3
+ use std::{sync::Arc, time::Duration};
4
+ use temporalio_client::{ActivityIdentifier, WorkflowStartOptions};
5
+ use temporalio_common::protos::{
6
+ coresdk::{AsJsonPayloadExt, workflow_commands::ActivityCancellationType},
7
+ temporal::api::{
8
+ common::v1::RetryPolicy,
9
+ failure::v1::{ApplicationFailureInfo, Failure, failure::FailureInfo},
10
+ },
11
+ };
12
+ use temporalio_macros::{activities, workflow, workflow_methods};
13
+ use temporalio_sdk::{
14
+ ActivityExecutionError, ActivityOptions, CancellableFuture, WorkflowContext, WorkflowResult,
15
+ activities::{ActivityContext, ActivityError},
16
+ };
17
+ use tokio::sync::mpsc;
18
+
19
+ #[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
20
+ enum Outcome {
21
+ Success,
22
+ Failure,
23
+ Cancellation,
24
+ }
25
+
26
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
27
+ enum IdentifierType {
28
+ TaskToken,
29
+ ById,
30
+ }
31
+
32
+ #[rstest]
33
+ #[tokio::test]
34
+ async fn async_activity_completions(
35
+ #[values(Outcome::Success, Outcome::Failure, Outcome::Cancellation)] outcome: Outcome,
36
+ #[values(IdentifierType::TaskToken, IdentifierType::ById)] identifier_type: IdentifierType,
37
+ ) {
38
+ let wf_name = format!("async_activity_{outcome:?}_{identifier_type:?}");
39
+ let mut starter = CoreWfStarter::new(&wf_name);
40
+ // Speeds up cancel test
41
+ starter.set_core_cfg_mutator(|wc| wc.max_heartbeat_throttle_interval = Duration::from_secs(1));
42
+ let async_response = "agence";
43
+
44
+ #[derive(Clone)]
45
+ struct SharedActivityInfo {
46
+ task_token: Vec<u8>,
47
+ workflow_id: String,
48
+ run_id: String,
49
+ activity_id: String,
50
+ }
51
+
52
+ let (info_tx, mut info_rx) = mpsc::channel::<SharedActivityInfo>(1);
53
+
54
+ struct AsyncActivities {
55
+ info_tx: mpsc::Sender<SharedActivityInfo>,
56
+ }
57
+ #[activities]
58
+ impl AsyncActivities {
59
+ #[activity]
60
+ async fn complete_async_activity(
61
+ self: Arc<Self>,
62
+ ctx: ActivityContext,
63
+ expected_outcome: Outcome,
64
+ ) -> Result<String, ActivityError> {
65
+ // For cancellation, wait until the workflow has requested cancellation
66
+ if expected_outcome == Outcome::Cancellation {
67
+ tokio::select! {
68
+ _ = async {
69
+ loop {
70
+ ctx.record_heartbeat(vec![]);
71
+ tokio::time::sleep(Duration::from_millis(500)).await;
72
+ }
73
+ } => (),
74
+ _ = ctx.cancelled() => (),
75
+ }
76
+ }
77
+
78
+ let activity_info = ctx.info();
79
+ let wf_exec = activity_info.workflow_execution.as_ref().unwrap();
80
+ let info = SharedActivityInfo {
81
+ task_token: activity_info.task_token.clone(),
82
+ workflow_id: wf_exec.workflow_id.clone(),
83
+ run_id: wf_exec.run_id.clone(),
84
+ activity_id: activity_info.activity_id.clone(),
85
+ };
86
+ let _ = self.info_tx.send(info).await;
87
+ Err(ActivityError::WillCompleteAsync)
88
+ }
89
+ }
90
+
91
+ starter
92
+ .sdk_config
93
+ .register_activities(AsyncActivities { info_tx });
94
+
95
+ let mut worker = starter.worker().await;
96
+ let client = starter.get_client().await;
97
+
98
+ #[workflow]
99
+ #[derive(Default)]
100
+ struct AsyncCompletionWorkflow;
101
+
102
+ #[workflow_methods]
103
+ impl AsyncCompletionWorkflow {
104
+ #[run]
105
+ async fn run(
106
+ ctx: &mut WorkflowContext<Self>,
107
+ expected_outcome: Outcome,
108
+ ) -> WorkflowResult<()> {
109
+ let async_response = "agence";
110
+ let activity_future = ctx.start_activity(
111
+ AsyncActivities::complete_async_activity,
112
+ expected_outcome,
113
+ ActivityOptions {
114
+ start_to_close_timeout: Some(Duration::from_secs(30)),
115
+ retry_policy: Some(RetryPolicy {
116
+ maximum_attempts: 1,
117
+ ..Default::default()
118
+ }),
119
+ cancellation_type: ActivityCancellationType::WaitCancellationCompleted,
120
+ ..Default::default()
121
+ },
122
+ );
123
+
124
+ // For cancellation, wait a bit to let the activity start, then request cancel
125
+ if expected_outcome == Outcome::Cancellation {
126
+ ctx.timer(Duration::from_millis(1)).await;
127
+ activity_future.cancel();
128
+ }
129
+
130
+ let activity_result = activity_future.await;
131
+
132
+ match expected_outcome {
133
+ Outcome::Success => {
134
+ assert_eq!(activity_result.expect("expected success"), async_response);
135
+ }
136
+ Outcome::Failure => {
137
+ let err = activity_result.expect_err("expected failure");
138
+ if let ActivityExecutionError::Failed(failure) = err {
139
+ // The failure we sent is wrapped as the cause
140
+ let cause = failure.cause.expect("cause should be present");
141
+ assert_eq!(cause.message, "async failure reason");
142
+ } else {
143
+ panic!("expected Failed, got {err:?}");
144
+ }
145
+ }
146
+ Outcome::Cancellation => {
147
+ let err = activity_result.expect_err("expected cancellation");
148
+ assert!(
149
+ matches!(err, ActivityExecutionError::Cancelled(_)),
150
+ "expected Cancelled, got {err:?}"
151
+ );
152
+ }
153
+ }
154
+ Ok(())
155
+ }
156
+ }
157
+
158
+ worker.register_workflow::<AsyncCompletionWorkflow>();
159
+
160
+ let completion_task = tokio::spawn(async move {
161
+ let info = info_rx.recv().await.expect("should receive activity info");
162
+
163
+ eprintln!(
164
+ "DEBUG: Received activity info - task_token_len={}, workflow_id={}, run_id={}, activity_id={}",
165
+ info.task_token.len(),
166
+ info.workflow_id,
167
+ info.run_id,
168
+ info.activity_id
169
+ );
170
+
171
+ let identifier = match identifier_type {
172
+ IdentifierType::TaskToken => {
173
+ eprintln!("DEBUG: Using TaskToken identifier");
174
+ ActivityIdentifier::TaskToken(info.task_token.into())
175
+ }
176
+ IdentifierType::ById => {
177
+ eprintln!("DEBUG: Using ById identifier");
178
+ ActivityIdentifier::by_id(info.workflow_id, info.run_id, info.activity_id)
179
+ }
180
+ };
181
+
182
+ let handle = client.get_async_activity_handle(identifier);
183
+ eprintln!("DEBUG: Calling {:?} on handle", outcome);
184
+
185
+ let result = match outcome {
186
+ Outcome::Success => {
187
+ handle
188
+ .complete(Some(async_response.as_json_payload().unwrap().into()))
189
+ .await
190
+ }
191
+ Outcome::Failure => {
192
+ handle
193
+ .fail(
194
+ Failure {
195
+ message: "async failure reason".to_string(),
196
+ failure_info: Some(FailureInfo::ApplicationFailureInfo(
197
+ ApplicationFailureInfo {
198
+ r#type: "TestFailure".to_string(),
199
+ ..Default::default()
200
+ },
201
+ )),
202
+ ..Default::default()
203
+ },
204
+ None,
205
+ )
206
+ .await
207
+ }
208
+ Outcome::Cancellation => handle.report_cancelation(None).await,
209
+ };
210
+ if let Err(e) = &result {
211
+ eprintln!(
212
+ "ERROR: async activity completion failed: {e:?} (outcome={outcome:?}, identifier={identifier_type:?})"
213
+ );
214
+ }
215
+ result.expect("async activity completion should succeed");
216
+ });
217
+
218
+ let task_queue = starter.get_task_queue().to_owned();
219
+ worker
220
+ .submit_workflow(
221
+ AsyncCompletionWorkflow::run,
222
+ outcome,
223
+ WorkflowStartOptions::new(task_queue, wf_name).build(),
224
+ )
225
+ .await
226
+ .unwrap();
227
+
228
+ worker.run_until_done().await.unwrap();
229
+ completion_task.await.unwrap();
230
+ }
@@ -18,13 +18,13 @@ use std::{
18
18
  time::Duration,
19
19
  };
20
20
  use temporalio_client::{
21
- Namespace, RETRYABLE_ERROR_CODES, RetryOptions, WorkflowClientTrait, WorkflowService,
22
- proxy::HttpConnectProxyOptions,
21
+ Connection, Namespace, RETRYABLE_ERROR_CODES, RetryOptions, UntypedWorkflow,
22
+ grpc::WorkflowService, proxy::HttpConnectProxyOptions,
23
23
  };
24
24
  use temporalio_common::protos::temporal::api::{
25
25
  cloud::cloudservice::v1::GetNamespaceRequest,
26
26
  workflowservice::v1::{
27
- DescribeNamespaceRequest, GetWorkflowExecutionHistoryRequest,
27
+ DescribeNamespaceRequest, GetWorkflowExecutionHistoryRequest, ListNamespacesRequest,
28
28
  RespondActivityTaskCanceledResponse,
29
29
  },
30
30
  };
@@ -42,7 +42,12 @@ async fn can_use_retry_client() {
42
42
  let mut core = CoreWfStarter::new("retry_client");
43
43
  let retry_client = core.get_client().await;
44
44
  for _ in 0..10 {
45
- retry_client.list_namespaces().await.unwrap();
45
+ WorkflowService::list_namespaces(
46
+ &mut retry_client.clone(),
47
+ ListNamespacesRequest::default().into_request(),
48
+ )
49
+ .await
50
+ .unwrap();
46
51
  tokio::time::sleep(Duration::from_millis(10)).await;
47
52
  }
48
53
  }
@@ -50,8 +55,8 @@ async fn can_use_retry_client() {
50
55
  #[tokio::test]
51
56
  async fn can_use_retry_raw_client() {
52
57
  let opts = get_integ_server_options();
53
- let mut client = opts.connect_no_namespace(None).await.unwrap();
54
- client
58
+ let mut connection = Connection::connect(opts).await.unwrap();
59
+ connection
55
60
  .describe_namespace(
56
61
  DescribeNamespaceRequest {
57
62
  namespace: NAMESPACE.to_string(),
@@ -66,18 +71,18 @@ async fn can_use_retry_raw_client() {
66
71
  #[tokio::test]
67
72
  async fn calls_get_system_info() {
68
73
  let opts = get_integ_server_options();
69
- let raw_client = opts.connect_no_namespace(None).await.unwrap();
70
- assert!(raw_client.get_client().capabilities().is_some());
74
+ let connection = Connection::connect(opts).await.unwrap();
75
+ assert!(connection.capabilities().is_some());
71
76
  }
72
77
 
73
78
  #[tokio::test]
74
79
  async fn per_call_timeout_respected_whole_client() {
75
80
  let opts = get_integ_server_options();
76
- let mut raw_client = opts.connect_no_namespace(None).await.unwrap();
81
+ let mut connection = Connection::connect(opts).await.unwrap();
77
82
  let mut hm = HashMap::new();
78
83
  hm.insert("grpc-timeout".to_string(), "0S".to_string());
79
- raw_client.get_client().set_headers(hm).unwrap();
80
- let err = raw_client
84
+ connection.set_headers(hm).unwrap();
85
+ let err = connection
81
86
  .describe_namespace(
82
87
  DescribeNamespaceRequest {
83
88
  namespace: NAMESPACE.to_string(),
@@ -93,14 +98,14 @@ async fn per_call_timeout_respected_whole_client() {
93
98
  #[tokio::test]
94
99
  async fn per_call_timeout_respected_one_call() {
95
100
  let opts = get_integ_server_options();
96
- let mut client = opts.connect_no_namespace(None).await.unwrap();
101
+ let mut connection = Connection::connect(opts).await.unwrap();
97
102
 
98
103
  let mut req = Request::new(DescribeNamespaceRequest {
99
104
  namespace: NAMESPACE.to_string(),
100
105
  ..Default::default()
101
106
  });
102
107
  req.set_timeout(Duration::from_millis(0));
103
- let res = client.describe_namespace(req).await;
108
+ let res = connection.describe_namespace(req).await;
104
109
  assert_matches!(
105
110
  res.unwrap_err().code(),
106
111
  Code::DeadlineExceeded | Code::Cancelled
@@ -113,14 +118,13 @@ async fn timeouts_respected_one_call_fake_server() {
113
118
  let header_rx = &mut fs.header_rx;
114
119
 
115
120
  let mut opts = get_integ_server_options();
116
- let uri = format!("http://localhost:{}", fs.addr.port())
117
- .parse()
121
+ opts.target = format!("http://localhost:{}", fs.addr.port())
122
+ .parse::<url::Url>()
118
123
  .unwrap();
119
- opts.target_url = uri;
120
- opts.skip_get_system_info = true;
124
+ opts.set_skip_get_system_info(true);
121
125
  opts.retry_options = RetryOptions::no_retries();
122
126
 
123
- let mut client = opts.connect_no_namespace(None).await.unwrap();
127
+ let mut connection = Connection::connect(opts).await.unwrap();
124
128
 
125
129
  macro_rules! call_client {
126
130
  ($client:ident, $trx:ident, $client_fn:ident, $msg:expr) => {
@@ -134,13 +138,13 @@ async fn timeouts_respected_one_call_fake_server() {
134
138
  }
135
139
 
136
140
  call_client!(
137
- client,
141
+ connection,
138
142
  header_rx,
139
143
  get_workflow_execution_history,
140
144
  Default::default()
141
145
  );
142
146
  call_client!(
143
- client,
147
+ connection,
144
148
  header_rx,
145
149
  get_workflow_execution_history,
146
150
  GetWorkflowExecutionHistoryRequest {
@@ -150,13 +154,13 @@ async fn timeouts_respected_one_call_fake_server() {
150
154
  }
151
155
  );
152
156
  call_client!(
153
- client,
157
+ connection,
154
158
  header_rx,
155
159
  update_workflow_execution,
156
160
  Default::default()
157
161
  );
158
162
  call_client!(
159
- client,
163
+ connection,
160
164
  header_rx,
161
165
  poll_workflow_execution_update,
162
166
  Default::default()
@@ -185,14 +189,15 @@ async fn non_retryable_errors() {
185
189
  .await;
186
190
 
187
191
  let mut opts = get_integ_server_options();
188
- let uri = format!("http://localhost:{}", fs.addr.port())
189
- .parse()
192
+ opts.target = format!("http://localhost:{}", fs.addr.port())
193
+ .parse::<url::Url>()
190
194
  .unwrap();
191
- opts.target_url = uri;
192
- opts.skip_get_system_info = true;
193
- let client = opts.connect("ns", None).await.unwrap();
195
+ opts.set_skip_get_system_info(true);
196
+ let connection = Connection::connect(opts).await.unwrap();
197
+ let client_opts = temporalio_client::ClientOptions::new("ns").build();
198
+ let client = temporalio_client::Client::new(connection, client_opts).unwrap();
194
199
 
195
- let result = client.cancel_activity_task(vec![1].into(), None).await;
200
+ let result = client.count_workflows("whatever", Default::default()).await;
196
201
 
197
202
  // Expecting an error after a single attempt, since there was a non-retryable error.
198
203
  assert!(result.is_err());
@@ -225,17 +230,18 @@ async fn retryable_errors() {
225
230
  .await;
226
231
 
227
232
  let mut opts = get_integ_server_options();
228
- let uri = format!("http://localhost:{}", fs.addr.port())
229
- .parse()
233
+ opts.target = format!("http://localhost:{}", fs.addr.port())
234
+ .parse::<url::Url>()
230
235
  .unwrap();
231
- opts.target_url = uri;
232
- opts.skip_get_system_info = true;
233
- let client = opts.connect("ns", None).await.unwrap();
236
+ opts.set_skip_get_system_info(true);
237
+ let connection = Connection::connect(opts).await.unwrap();
238
+ let client_opts = temporalio_client::ClientOptions::new("ns").build();
239
+ let client = temporalio_client::Client::new(connection, client_opts).unwrap();
234
240
 
235
- let result = client.cancel_activity_task(vec![1].into(), None).await;
241
+ let result = client.count_workflows("whatever", Default::default()).await;
236
242
 
237
243
  // Expecting successful response after retries
238
- assert!(result.is_ok());
244
+ assert!(result.is_ok(), "{:?}", result);
239
245
  let mut all_calls = vec![];
240
246
  fs.header_rx.recv_many(&mut all_calls, 9999).await;
241
247
  // Should be 4 attempts
@@ -269,27 +275,38 @@ async fn namespace_header_attached_to_relevant_calls() {
269
275
  .unwrap();
270
276
  });
271
277
 
278
+ let namespace = "namespace";
272
279
  let mut opts = get_integ_server_options();
273
- let uri = format!("http://localhost:{}", addr.port()).parse().unwrap();
274
- opts.target_url = uri;
275
- opts.skip_get_system_info = true;
280
+ opts.target = format!("http://localhost:{}", addr.port())
281
+ .parse::<url::Url>()
282
+ .unwrap();
283
+ opts.set_skip_get_system_info(true);
276
284
  opts.retry_options = RetryOptions::no_retries();
277
-
278
- let namespace = "namespace";
279
- let client = opts.connect(namespace, None).await.unwrap();
285
+ let connection = Connection::connect(opts).await.unwrap();
286
+ let client_opts = temporalio_client::ClientOptions::new(namespace).build();
287
+ let client = temporalio_client::Client::new(connection, client_opts).unwrap();
280
288
 
281
289
  let _ = client
282
- .get_workflow_execution_history("hi".to_string(), None, vec![])
290
+ .get_workflow_handle::<UntypedWorkflow>("hi")
291
+ .fetch_history(Default::default())
283
292
  .await;
284
293
  let val = header_rx.recv().await.unwrap();
285
294
  assert_eq!(namespace, val);
286
- let _ = client.list_namespaces().await;
295
+ let _ = WorkflowService::list_namespaces(
296
+ &mut client.clone(),
297
+ ListNamespacesRequest::default().into_request(),
298
+ )
299
+ .await;
287
300
  let val = header_rx.recv().await.unwrap();
288
301
  // List namespaces is not namespace-specific
289
302
  assert_eq!("", val);
290
- let _ = client
291
- .describe_namespace(Namespace::Name("Other".to_string()))
292
- .await;
303
+ let _ = WorkflowService::describe_namespace(
304
+ &mut client.clone(),
305
+ Namespace::Name("Other".to_string())
306
+ .into_describe_namespace_request()
307
+ .into_request(),
308
+ )
309
+ .await;
293
310
  let val = header_rx.recv().await.unwrap();
294
311
  assert_eq!("Other", val);
295
312
 
@@ -313,15 +330,17 @@ async fn cloud_ops_test() {
313
330
  let namespace =
314
331
  env::var("TEMPORAL_CLIENT_CLOUD_NAMESPACE").expect("namespace env var must exist");
315
332
  let mut opts = get_integ_server_options();
316
- opts.target_url = "saas-api.tmprl.cloud:443".parse().unwrap();
333
+ opts.target = "https://saas-api.tmprl.cloud:443"
334
+ .parse::<url::Url>()
335
+ .unwrap();
317
336
  opts.api_key = Some(api_key);
318
337
  opts.headers = Some({
319
338
  let mut hm = HashMap::new();
320
339
  hm.insert("temporal-cloud-api-version".to_string(), api_version);
321
340
  hm
322
341
  });
323
- let client = opts.connect_no_namespace(None).await.unwrap().into_inner();
324
- let mut cloud_client = client.cloud_svc();
342
+ let connection = Connection::connect(opts).await.unwrap();
343
+ let mut cloud_client = connection.cloud_service();
325
344
  let res = cloud_client
326
345
  .get_namespace(
327
346
  GetNamespaceRequest {
@@ -353,14 +372,20 @@ async fn http_proxy() {
353
372
  // General client options
354
373
  let mut opts = get_integ_server_options();
355
374
  opts.retry_options = RetryOptions::no_retries();
356
- opts.skip_get_system_info = true;
375
+ opts.set_skip_get_system_info(true);
357
376
 
358
377
  // Connect client with no proxy and make call and confirm reached
359
- opts.target_url = format!("http://127.0.0.1:{}", server.addr.port())
378
+ opts.target = format!("http://127.0.0.1:{}", server.addr.port())
360
379
  .parse()
361
380
  .unwrap();
362
- let client = opts.connect("my-namespace", None).await.unwrap();
363
- let _ = client.list_namespaces().await;
381
+ let connection = Connection::connect(opts.clone()).await.unwrap();
382
+ let client_opts = temporalio_client::ClientOptions::new("my-namespace").build();
383
+ let client = temporalio_client::Client::new(connection, client_opts).unwrap();
384
+ let _ = WorkflowService::list_namespaces(
385
+ &mut client.clone(),
386
+ ListNamespacesRequest::default().into_request(),
387
+ )
388
+ .await;
364
389
  assert!(call_count.load(Ordering::SeqCst) == 1);
365
390
  assert!(tcp_proxy.hit_count() == 0);
366
391
 
@@ -369,8 +394,14 @@ async fn http_proxy() {
369
394
  target_addr: tcp_proxy_addr.to_string(),
370
395
  basic_auth: None,
371
396
  });
372
- let proxied_client = opts.connect("my-namespace", None).await.unwrap();
373
- let _ = proxied_client.list_namespaces().await;
397
+ let connection = Connection::connect(opts.clone()).await.unwrap();
398
+ let client_opts = temporalio_client::ClientOptions::new("my-namespace").build();
399
+ let proxied_client = temporalio_client::Client::new(connection, client_opts).unwrap();
400
+ let _ = WorkflowService::list_namespaces(
401
+ &mut proxied_client.clone(),
402
+ ListNamespacesRequest::default().into_request(),
403
+ )
404
+ .await;
374
405
  assert!(call_count.load(Ordering::SeqCst) == 2);
375
406
  assert!(tcp_proxy.hit_count() == 1);
376
407
 
@@ -391,8 +422,14 @@ async fn http_proxy() {
391
422
  target_addr: format!("unix:{}", sock_path.to_str().unwrap()),
392
423
  basic_auth: None,
393
424
  });
394
- let proxied_client = opts.connect("my-namespace", None).await.unwrap();
395
- let _ = proxied_client.list_namespaces().await;
425
+ let connection = Connection::connect(opts.clone()).await.unwrap();
426
+ let client_opts = temporalio_client::ClientOptions::new("my-namespace").build();
427
+ let proxied_client = temporalio_client::Client::new(connection, client_opts).unwrap();
428
+ let _ = WorkflowService::list_namespaces(
429
+ &mut proxied_client.clone(),
430
+ ListNamespacesRequest::default().into_request(),
431
+ )
432
+ .await;
396
433
  assert!(call_count.load(Ordering::SeqCst) == 3);
397
434
  assert!(unix_proxy.hit_count() == 1);
398
435