@temporalio/core-bridge 1.1.0 → 1.3.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 (114) hide show
  1. package/Cargo.lock +786 -54
  2. package/Cargo.toml +2 -2
  3. package/common.js +7 -3
  4. package/index.d.ts +110 -3
  5. package/index.js +2 -6
  6. package/package.json +3 -3
  7. package/releases/aarch64-apple-darwin/index.node +0 -0
  8. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  9. package/releases/x86_64-apple-darwin/index.node +0 -0
  10. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  11. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  12. package/scripts/build.js +4 -3
  13. package/sdk-core/.buildkite/docker/Dockerfile +2 -1
  14. package/sdk-core/ARCHITECTURE.md +2 -2
  15. package/sdk-core/README.md +12 -0
  16. package/sdk-core/bridge-ffi/Cargo.toml +2 -2
  17. package/sdk-core/client/Cargo.toml +6 -4
  18. package/sdk-core/client/src/lib.rs +338 -215
  19. package/sdk-core/client/src/raw.rs +352 -106
  20. package/sdk-core/client/src/retry.rs +159 -133
  21. package/sdk-core/client/src/workflow_handle/mod.rs +1 -1
  22. package/sdk-core/core/Cargo.toml +18 -9
  23. package/sdk-core/core/src/core_tests/activity_tasks.rs +63 -23
  24. package/sdk-core/core/src/core_tests/child_workflows.rs +125 -3
  25. package/sdk-core/core/src/core_tests/local_activities.rs +6 -6
  26. package/sdk-core/core/src/core_tests/workers.rs +3 -2
  27. package/sdk-core/core/src/core_tests/workflow_tasks.rs +70 -2
  28. package/sdk-core/core/src/ephemeral_server/mod.rs +499 -0
  29. package/sdk-core/core/src/lib.rs +60 -26
  30. package/sdk-core/core/src/pollers/poll_buffer.rs +4 -4
  31. package/sdk-core/core/src/replay/mod.rs +3 -3
  32. package/sdk-core/core/src/retry_logic.rs +10 -9
  33. package/sdk-core/core/src/telemetry/mod.rs +10 -7
  34. package/sdk-core/core/src/test_help/mod.rs +18 -8
  35. package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +10 -10
  36. package/sdk-core/core/src/worker/activities/local_activities.rs +13 -13
  37. package/sdk-core/core/src/worker/activities.rs +6 -12
  38. package/sdk-core/core/src/worker/client.rs +193 -64
  39. package/sdk-core/core/src/worker/mod.rs +14 -19
  40. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -0
  41. package/sdk-core/core/src/worker/workflow/history_update.rs +5 -5
  42. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +133 -85
  43. package/sdk-core/core/src/worker/workflow/machines/mod.rs +3 -2
  44. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +160 -105
  45. package/sdk-core/core/src/worker/workflow/managed_run.rs +2 -1
  46. package/sdk-core/core/src/worker/workflow/mod.rs +59 -58
  47. package/sdk-core/core/src/worker/workflow/run_cache.rs +5 -3
  48. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +7 -5
  49. package/sdk-core/core-api/Cargo.toml +2 -2
  50. package/sdk-core/core-api/src/errors.rs +3 -11
  51. package/sdk-core/core-api/src/worker.rs +7 -0
  52. package/sdk-core/protos/api_upstream/.buildkite/Dockerfile +1 -1
  53. package/sdk-core/protos/api_upstream/.github/CODEOWNERS +1 -1
  54. package/sdk-core/protos/api_upstream/.github/PULL_REQUEST_TEMPLATE.md +2 -6
  55. package/sdk-core/protos/api_upstream/.github/workflows/trigger-api-go-update.yml +29 -0
  56. package/sdk-core/protos/api_upstream/Makefile +2 -2
  57. package/sdk-core/protos/api_upstream/buf.yaml +1 -0
  58. package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +86 -0
  59. package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +26 -0
  60. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +46 -0
  61. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +7 -0
  62. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +14 -0
  63. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +51 -0
  64. package/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +18 -0
  65. package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +57 -1
  66. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +1 -3
  67. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +4 -2
  68. package/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +11 -0
  69. package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +23 -0
  70. package/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +46 -0
  71. package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +1 -0
  72. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +172 -0
  73. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +30 -0
  74. package/sdk-core/protos/grpc/health/v1/health.proto +63 -0
  75. package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +18 -15
  76. package/sdk-core/protos/testsrv_upstream/Makefile +80 -0
  77. package/sdk-core/protos/testsrv_upstream/api-linter.yaml +38 -0
  78. package/sdk-core/protos/testsrv_upstream/buf.yaml +13 -0
  79. package/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +141 -0
  80. package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +63 -0
  81. package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +90 -0
  82. package/sdk-core/sdk/Cargo.toml +2 -2
  83. package/sdk-core/sdk/src/lib.rs +2 -2
  84. package/sdk-core/sdk/src/workflow_context/options.rs +36 -8
  85. package/sdk-core/sdk/src/workflow_context.rs +30 -6
  86. package/sdk-core/sdk/src/workflow_future.rs +4 -4
  87. package/sdk-core/sdk-core-protos/Cargo.toml +5 -5
  88. package/sdk-core/sdk-core-protos/build.rs +9 -1
  89. package/sdk-core/sdk-core-protos/src/history_builder.rs +6 -1
  90. package/sdk-core/sdk-core-protos/src/lib.rs +93 -32
  91. package/sdk-core/test-utils/Cargo.toml +3 -3
  92. package/sdk-core/test-utils/src/canned_histories.rs +58 -0
  93. package/sdk-core/test-utils/src/lib.rs +14 -10
  94. package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +141 -0
  95. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +55 -5
  96. package/sdk-core/tests/integ_tests/polling_tests.rs +1 -1
  97. package/sdk-core/tests/integ_tests/queries_tests.rs +4 -4
  98. package/sdk-core/tests/integ_tests/visibility_tests.rs +93 -0
  99. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +93 -10
  100. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
  101. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +14 -14
  102. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +1 -1
  103. package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +12 -12
  104. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +12 -1
  105. package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +3 -3
  106. package/sdk-core/tests/integ_tests/workflow_tests.rs +19 -4
  107. package/sdk-core/tests/load_tests.rs +2 -1
  108. package/sdk-core/tests/main.rs +10 -0
  109. package/src/conversions.rs +138 -91
  110. package/src/helpers.rs +190 -0
  111. package/src/lib.rs +10 -912
  112. package/src/runtime.rs +436 -0
  113. package/src/testing.rs +67 -0
  114. package/src/worker.rs +465 -0
@@ -5,29 +5,44 @@
5
5
  use crate::{
6
6
  metrics::{namespace_kv, task_queue_kv},
7
7
  raw::sealed::RawClientLike,
8
+ Client, ConfiguredClient, InterceptedMetricsSvc, RetryClient, TemporalServiceClient,
8
9
  LONG_POLL_TIMEOUT,
9
10
  };
10
- use futures::{future::BoxFuture, FutureExt};
11
- use temporal_sdk_core_protos::temporal::api::{
12
- taskqueue::v1::TaskQueue, workflowservice::v1::workflow_service_client::WorkflowServiceClient,
11
+ use futures::{future::BoxFuture, FutureExt, TryFutureExt};
12
+ use temporal_sdk_core_protos::{
13
+ grpc::health::v1::{health_client::HealthClient, *},
14
+ temporal::api::{
15
+ operatorservice::v1::{operator_service_client::OperatorServiceClient, *},
16
+ taskqueue::v1::TaskQueue,
17
+ testservice::v1::{test_service_client::TestServiceClient, *},
18
+ workflowservice::v1::{workflow_service_client::WorkflowServiceClient, *},
19
+ },
20
+ };
21
+ use tonic::{
22
+ body::BoxBody, client::GrpcService, metadata::KeyAndValueRef, Request, Response, Status,
13
23
  };
14
- use tonic::{body::BoxBody, client::GrpcService, metadata::KeyAndValueRef};
15
24
 
16
25
  pub(super) mod sealed {
17
26
  use super::*;
18
- use crate::{Client, ConfiguredClient, InterceptedMetricsSvc, RetryClient};
19
- use futures::TryFutureExt;
20
- use tonic::{Request, Response, Status};
21
27
 
22
28
  /// Something that has a workflow service client
23
29
  #[async_trait::async_trait]
24
30
  pub trait RawClientLike: Send {
25
31
  type SvcType: Send + Sync + Clone + 'static;
26
32
 
27
- /// Return the actual client instance
28
- fn client(&mut self) -> &mut WorkflowServiceClient<Self::SvcType>;
33
+ /// Return the workflow service client instance
34
+ fn workflow_client(&mut self) -> &mut WorkflowServiceClient<Self::SvcType>;
35
+
36
+ /// Return the operator service client instance
37
+ fn operator_client(&mut self) -> &mut OperatorServiceClient<Self::SvcType>;
38
+
39
+ /// Return the test service client instance
40
+ fn test_client(&mut self) -> &mut TestServiceClient<Self::SvcType>;
29
41
 
30
- async fn do_call<F, Req, Resp>(
42
+ /// Return the health service client instance
43
+ fn health_client(&mut self) -> &mut HealthClient<Self::SvcType>;
44
+
45
+ async fn call<F, Req, Resp>(
31
46
  &mut self,
32
47
  _call_name: &'static str,
33
48
  mut callfn: F,
@@ -35,90 +50,140 @@ pub(super) mod sealed {
35
50
  ) -> Result<Response<Resp>, Status>
36
51
  where
37
52
  Req: Clone + Unpin + Send + Sync + 'static,
38
- F: FnMut(
39
- &mut WorkflowServiceClient<Self::SvcType>,
40
- Request<Req>,
41
- ) -> BoxFuture<'static, Result<Response<Resp>, Status>>,
53
+ F: FnMut(&mut Self, Request<Req>) -> BoxFuture<'static, Result<Response<Resp>, Status>>,
42
54
  F: Send + Sync + Unpin + 'static,
43
55
  {
44
- callfn(self.client(), req).await
56
+ callfn(self, req).await
45
57
  }
46
58
  }
59
+ }
47
60
 
48
- // Here we implement retry on anything that is already RawClientLike
49
- #[async_trait::async_trait]
50
- impl<RC, T> RawClientLike for RetryClient<RC>
51
- where
52
- RC: RawClientLike<SvcType = T> + 'static,
53
- T: Send + Sync + Clone + 'static,
54
- {
55
- type SvcType = T;
61
+ // Here we implement retry on anything that is already RawClientLike
62
+ #[async_trait::async_trait]
63
+ impl<RC, T> RawClientLike for RetryClient<RC>
64
+ where
65
+ RC: RawClientLike<SvcType = T> + 'static,
66
+ T: Send + Sync + Clone + 'static,
67
+ {
68
+ type SvcType = T;
56
69
 
57
- fn client(&mut self) -> &mut WorkflowServiceClient<Self::SvcType> {
58
- self.get_client_mut().client()
59
- }
70
+ fn workflow_client(&mut self) -> &mut WorkflowServiceClient<Self::SvcType> {
71
+ self.get_client_mut().workflow_client()
72
+ }
60
73
 
61
- async fn do_call<F, Req, Resp>(
62
- &mut self,
63
- call_name: &'static str,
64
- mut callfn: F,
65
- req: Request<Req>,
66
- ) -> Result<Response<Resp>, Status>
67
- where
68
- Req: Clone + Unpin + Send + Sync + 'static,
69
- F: FnMut(
70
- &mut WorkflowServiceClient<Self::SvcType>,
71
- Request<Req>,
72
- ) -> BoxFuture<'static, Result<Response<Resp>, Status>>,
73
- F: Send + Sync + Unpin + 'static,
74
- {
75
- let rtc = self.get_retry_config(call_name);
76
- let req = req_cloner(&req);
77
- let fact = || {
78
- let req_clone = req_cloner(&req);
79
- callfn(self.client(), req_clone)
80
- };
81
- let res = Self::make_future_retry(rtc, fact, call_name);
82
- res.map_err(|(e, _attempt)| e).map_ok(|x| x.0).await
83
- }
74
+ fn operator_client(&mut self) -> &mut OperatorServiceClient<Self::SvcType> {
75
+ self.get_client_mut().operator_client()
84
76
  }
85
77
 
86
- impl<T> RawClientLike for WorkflowServiceClient<T>
87
- where
88
- T: Send + Sync + Clone + 'static,
89
- {
90
- type SvcType = T;
78
+ fn test_client(&mut self) -> &mut TestServiceClient<Self::SvcType> {
79
+ self.get_client_mut().test_client()
80
+ }
91
81
 
92
- fn client(&mut self) -> &mut WorkflowServiceClient<Self::SvcType> {
93
- self
94
- }
82
+ fn health_client(&mut self) -> &mut HealthClient<Self::SvcType> {
83
+ self.get_client_mut().health_client()
95
84
  }
96
85
 
97
- impl<T> RawClientLike for ConfiguredClient<WorkflowServiceClient<T>>
86
+ async fn call<F, Req, Resp>(
87
+ &mut self,
88
+ call_name: &'static str,
89
+ mut callfn: F,
90
+ req: Request<Req>,
91
+ ) -> Result<Response<Resp>, Status>
98
92
  where
99
- T: Send + Sync + Clone + 'static,
93
+ Req: Clone + Unpin + Send + Sync + 'static,
94
+ F: FnMut(&mut Self, Request<Req>) -> BoxFuture<'static, Result<Response<Resp>, Status>>,
95
+ F: Send + Sync + Unpin + 'static,
100
96
  {
101
- type SvcType = T;
97
+ let rtc = self.get_retry_config(call_name);
98
+ let req = req_cloner(&req);
99
+ let fact = || {
100
+ let req_clone = req_cloner(&req);
101
+ callfn(self, req_clone)
102
+ };
103
+ let res = Self::make_future_retry(rtc, fact, call_name);
104
+ res.map_err(|(e, _attempt)| e).map_ok(|x| x.0).await
105
+ }
106
+ }
102
107
 
103
- fn client(&mut self) -> &mut WorkflowServiceClient<Self::SvcType> {
104
- &mut self.client
105
- }
108
+ impl<T> RawClientLike for TemporalServiceClient<T>
109
+ where
110
+ T: Send + Sync + Clone + 'static,
111
+ T: GrpcService<BoxBody> + Send + Clone + 'static,
112
+ T::ResponseBody: tonic::codegen::Body<Data = tonic::codegen::Bytes> + Send + 'static,
113
+ T::Error: Into<tonic::codegen::StdError>,
114
+ <T::ResponseBody as tonic::codegen::Body>::Error: Into<tonic::codegen::StdError> + Send,
115
+ {
116
+ type SvcType = T;
117
+
118
+ fn workflow_client(&mut self) -> &mut WorkflowServiceClient<Self::SvcType> {
119
+ self.workflow_svc_mut()
106
120
  }
107
121
 
108
- impl RawClientLike for Client {
109
- type SvcType = InterceptedMetricsSvc;
122
+ fn operator_client(&mut self) -> &mut OperatorServiceClient<Self::SvcType> {
123
+ self.operator_svc_mut()
124
+ }
110
125
 
111
- fn client(&mut self) -> &mut WorkflowServiceClient<Self::SvcType> {
112
- &mut self.inner
113
- }
126
+ fn test_client(&mut self) -> &mut TestServiceClient<Self::SvcType> {
127
+ self.test_svc_mut()
128
+ }
129
+
130
+ fn health_client(&mut self) -> &mut HealthClient<Self::SvcType> {
131
+ self.health_svc_mut()
132
+ }
133
+ }
134
+
135
+ impl<T> RawClientLike for ConfiguredClient<TemporalServiceClient<T>>
136
+ where
137
+ T: Send + Sync + Clone + 'static,
138
+ T: GrpcService<BoxBody> + Send + Clone + 'static,
139
+ T::ResponseBody: tonic::codegen::Body<Data = tonic::codegen::Bytes> + Send + 'static,
140
+ T::Error: Into<tonic::codegen::StdError>,
141
+ <T::ResponseBody as tonic::codegen::Body>::Error: Into<tonic::codegen::StdError> + Send,
142
+ {
143
+ type SvcType = T;
144
+
145
+ fn workflow_client(&mut self) -> &mut WorkflowServiceClient<Self::SvcType> {
146
+ self.client.workflow_client()
147
+ }
148
+
149
+ fn operator_client(&mut self) -> &mut OperatorServiceClient<Self::SvcType> {
150
+ self.client.operator_client()
151
+ }
152
+
153
+ fn test_client(&mut self) -> &mut TestServiceClient<Self::SvcType> {
154
+ self.client.test_client()
155
+ }
156
+
157
+ fn health_client(&mut self) -> &mut HealthClient<Self::SvcType> {
158
+ self.client.health_client()
159
+ }
160
+ }
161
+
162
+ impl RawClientLike for Client {
163
+ type SvcType = InterceptedMetricsSvc;
164
+
165
+ fn workflow_client(&mut self) -> &mut WorkflowServiceClient<Self::SvcType> {
166
+ self.inner.workflow_client()
167
+ }
168
+
169
+ fn operator_client(&mut self) -> &mut OperatorServiceClient<Self::SvcType> {
170
+ self.inner.operator_client()
171
+ }
172
+
173
+ fn test_client(&mut self) -> &mut TestServiceClient<Self::SvcType> {
174
+ self.inner.test_client()
175
+ }
176
+
177
+ fn health_client(&mut self) -> &mut HealthClient<Self::SvcType> {
178
+ self.inner.health_client()
114
179
  }
115
180
  }
116
181
 
117
182
  /// Helper for cloning a tonic request as long as the inner message may be cloned.
118
183
  /// We drop extensions, so, lang bridges can't pass those in :shrug:
119
- fn req_cloner<T: Clone>(cloneme: &tonic::Request<T>) -> tonic::Request<T> {
184
+ fn req_cloner<T: Clone>(cloneme: &Request<T>) -> Request<T> {
120
185
  let msg = cloneme.get_ref().clone();
121
- let mut new_req = tonic::Request::new(msg);
186
+ let mut new_req = Request::new(msg);
122
187
  let new_met = new_req.metadata_mut();
123
188
  for kv in cloneme.metadata().iter() {
124
189
  match kv {
@@ -146,10 +211,14 @@ impl AttachMetricLabels {
146
211
  }
147
212
  pub fn task_q(&mut self, tq: Option<TaskQueue>) -> &mut Self {
148
213
  if let Some(tq) = tq {
149
- self.labels.push(task_queue_kv(tq.name));
214
+ self.task_q_str(tq.name);
150
215
  }
151
216
  self
152
217
  }
218
+ pub fn task_q_str(&mut self, tq: impl Into<String>) -> &mut Self {
219
+ self.labels.push(task_queue_kv(tq.into()));
220
+ self
221
+ }
153
222
  }
154
223
 
155
224
  // Blanket impl the trait for all raw-client-like things. Since the trait default-implements
@@ -158,7 +227,37 @@ impl<RC, T> WorkflowService for RC
158
227
  where
159
228
  RC: RawClientLike<SvcType = T>,
160
229
  T: GrpcService<BoxBody> + Send + Clone + 'static,
161
- T::ResponseBody: tonic::codegen::Body + Send + 'static,
230
+ T::ResponseBody: tonic::codegen::Body<Data = tonic::codegen::Bytes> + Send + 'static,
231
+ T::Error: Into<tonic::codegen::StdError>,
232
+ T::Future: Send,
233
+ <T::ResponseBody as tonic::codegen::Body>::Error: Into<tonic::codegen::StdError> + Send,
234
+ {
235
+ }
236
+ impl<RC, T> OperatorService for RC
237
+ where
238
+ RC: RawClientLike<SvcType = T>,
239
+ T: GrpcService<BoxBody> + Send + Clone + 'static,
240
+ T::ResponseBody: tonic::codegen::Body<Data = tonic::codegen::Bytes> + Send + 'static,
241
+ T::Error: Into<tonic::codegen::StdError>,
242
+ T::Future: Send,
243
+ <T::ResponseBody as tonic::codegen::Body>::Error: Into<tonic::codegen::StdError> + Send,
244
+ {
245
+ }
246
+ impl<RC, T> TestService for RC
247
+ where
248
+ RC: RawClientLike<SvcType = T>,
249
+ T: GrpcService<BoxBody> + Send + Clone + 'static,
250
+ T::ResponseBody: tonic::codegen::Body<Data = tonic::codegen::Bytes> + Send + 'static,
251
+ T::Error: Into<tonic::codegen::StdError>,
252
+ T::Future: Send,
253
+ <T::ResponseBody as tonic::codegen::Body>::Error: Into<tonic::codegen::StdError> + Send,
254
+ {
255
+ }
256
+ impl<RC, T> HealthService for RC
257
+ where
258
+ RC: RawClientLike<SvcType = T>,
259
+ T: GrpcService<BoxBody> + Send + Clone + 'static,
260
+ T::ResponseBody: tonic::codegen::Body<Data = tonic::codegen::Bytes> + Send + 'static,
162
261
  T::Error: Into<tonic::codegen::StdError>,
163
262
  T::Future: Send,
164
263
  <T::ResponseBody as tonic::codegen::Body>::Error: Into<tonic::codegen::StdError> + Send,
@@ -167,34 +266,35 @@ where
167
266
 
168
267
  /// Helps re-declare gRPC client methods
169
268
  macro_rules! proxy {
170
- ($method:ident, $req:ident, $resp:ident $(, $closure:expr)?) => {
171
- #[doc = concat!("See [WorkflowServiceClient::", stringify!($method), "]")]
269
+ ($client_type:tt, $client_meth:ident, $method:ident, $req:ty, $resp:ty $(, $closure:expr)?) => {
270
+ #[doc = concat!("See [", stringify!($client_type), "::", stringify!($method), "]")]
172
271
  fn $method(
173
272
  &mut self,
174
- request: impl tonic::IntoRequest<super::$req>,
175
- ) -> BoxFuture<Result<tonic::Response<super::$resp>, tonic::Status>> {
273
+ request: impl tonic::IntoRequest<$req>,
274
+ ) -> BoxFuture<Result<tonic::Response<$resp>, tonic::Status>> {
176
275
  #[allow(unused_mut)]
177
- let fact = |c: &mut WorkflowServiceClient<Self::SvcType>, mut req: tonic::Request<super::$req>| {
276
+ let fact = |c: &mut Self, mut req: tonic::Request<$req>| {
178
277
  $( type_closure_arg(&mut req, $closure); )*
179
- let mut c = c.clone();
278
+ let mut c = c.$client_meth().clone();
180
279
  async move { c.$method(req).await }.boxed()
181
280
  };
182
- self.do_call(stringify!($method), fact, request.into_request())
281
+ self.call(stringify!($method), fact, request.into_request())
183
282
  }
184
283
  };
185
284
  }
186
285
  macro_rules! proxier {
187
- ( $(($method:ident, $req:ident, $resp:ident $(, $closure:expr)? );)* ) => {
286
+ ( $trait_name:ident; $impl_list_name:ident; $client_type:tt; $client_meth:ident;
287
+ $(($method:ident, $req:ty, $resp:ty $(, $closure:expr)? );)* ) => {
188
288
  #[cfg(test)]
189
- const ALL_IMPLEMENTED_RPCS: &'static [&'static str] = &[$(stringify!($method)),*];
190
- /// Trait version of the generated workflow service client with modifications to attach appropriate
191
- /// metric labels or whatever else to requests
192
- pub trait WorkflowService: RawClientLike
289
+ const $impl_list_name: &'static [&'static str] = &[$(stringify!($method)),*];
290
+ /// Trait version of the generated client with modifications to attach appropriate metric
291
+ /// labels or whatever else to requests
292
+ pub trait $trait_name: RawClientLike
193
293
  where
194
294
  // Yo this is wild
195
295
  <Self as RawClientLike>::SvcType: GrpcService<BoxBody> + Send + Clone + 'static,
196
296
  <<Self as RawClientLike>::SvcType as GrpcService<BoxBody>>::ResponseBody:
197
- tonic::codegen::Body + Send + 'static,
297
+ tonic::codegen::Body<Data = tonic::codegen::Bytes> + Send + 'static,
198
298
  <<Self as RawClientLike>::SvcType as GrpcService<BoxBody>>::Error:
199
299
  Into<tonic::codegen::StdError>,
200
300
  <<Self as RawClientLike>::SvcType as GrpcService<BoxBody>>::Future: Send,
@@ -202,17 +302,19 @@ macro_rules! proxier {
202
302
  as tonic::codegen::Body>::Error: Into<tonic::codegen::StdError> + Send,
203
303
  {
204
304
  $(
205
- proxy!($method, $req, $resp $(,$closure)*);
305
+ proxy!($client_type, $client_meth, $method, $req, $resp $(,$closure)*);
206
306
  )*
207
307
  }
208
308
  };
209
309
  }
310
+
210
311
  // Nice little trick to avoid the callsite asking to type the closure parameter
211
312
  fn type_closure_arg<T, R>(arg: T, f: impl FnOnce(T) -> R) -> R {
212
313
  f(arg)
213
314
  }
214
315
 
215
316
  proxier! {
317
+ WorkflowService; ALL_IMPLEMENTED_WORKFLOW_SERVICE_RPCS; WorkflowServiceClient; workflow_client;
216
318
  (
217
319
  register_namespace,
218
320
  RegisterNamespaceRequest,
@@ -629,14 +731,121 @@ proxier! {
629
731
  r.extensions_mut().insert(labels);
630
732
  }
631
733
  );
734
+ (
735
+ update_worker_build_id_ordering,
736
+ UpdateWorkerBuildIdOrderingRequest,
737
+ UpdateWorkerBuildIdOrderingResponse,
738
+ |r| {
739
+ let mut labels = AttachMetricLabels::namespace(r.get_ref().namespace.clone());
740
+ labels.task_q_str(r.get_ref().task_queue.clone());
741
+ r.extensions_mut().insert(labels);
742
+ }
743
+ );
744
+ (
745
+ get_worker_build_id_ordering,
746
+ GetWorkerBuildIdOrderingRequest,
747
+ GetWorkerBuildIdOrderingResponse,
748
+ |r| {
749
+ let mut labels = AttachMetricLabels::namespace(r.get_ref().namespace.clone());
750
+ labels.task_q_str(r.get_ref().task_queue.clone());
751
+ r.extensions_mut().insert(labels);
752
+ }
753
+ );
754
+ (
755
+ update_workflow,
756
+ UpdateWorkflowRequest,
757
+ UpdateWorkflowResponse,
758
+ |r| {
759
+ let labels = AttachMetricLabels::namespace(r.get_ref().namespace.clone());
760
+ r.extensions_mut().insert(labels);
761
+ }
762
+ );
763
+ (
764
+ start_batch_operation,
765
+ StartBatchOperationRequest,
766
+ StartBatchOperationResponse,
767
+ |r| {
768
+ let labels = AttachMetricLabels::namespace(r.get_ref().namespace.clone());
769
+ r.extensions_mut().insert(labels);
770
+ }
771
+ );
772
+ (
773
+ stop_batch_operation,
774
+ StopBatchOperationRequest,
775
+ StopBatchOperationResponse,
776
+ |r| {
777
+ let labels = AttachMetricLabels::namespace(r.get_ref().namespace.clone());
778
+ r.extensions_mut().insert(labels);
779
+ }
780
+ );
781
+ (
782
+ describe_batch_operation,
783
+ DescribeBatchOperationRequest,
784
+ DescribeBatchOperationResponse,
785
+ |r| {
786
+ let labels = AttachMetricLabels::namespace(r.get_ref().namespace.clone());
787
+ r.extensions_mut().insert(labels);
788
+ }
789
+ );
790
+ (
791
+ list_batch_operations,
792
+ ListBatchOperationsRequest,
793
+ ListBatchOperationsResponse,
794
+ |r| {
795
+ let labels = AttachMetricLabels::namespace(r.get_ref().namespace.clone());
796
+ r.extensions_mut().insert(labels);
797
+ }
798
+ );
799
+ }
800
+
801
+ proxier! {
802
+ OperatorService; ALL_IMPLEMENTED_OPERATOR_SERVICE_RPCS; OperatorServiceClient; operator_client;
803
+ (add_search_attributes, AddSearchAttributesRequest, AddSearchAttributesResponse);
804
+ (remove_search_attributes, RemoveSearchAttributesRequest, RemoveSearchAttributesResponse);
805
+ (list_search_attributes, ListSearchAttributesRequest, ListSearchAttributesResponse);
806
+ (delete_namespace, DeleteNamespaceRequest, DeleteNamespaceResponse,
807
+ |r| {
808
+ let labels = AttachMetricLabels::namespace(r.get_ref().namespace.clone());
809
+ r.extensions_mut().insert(labels);
810
+ }
811
+ );
812
+ (delete_workflow_execution, DeleteWorkflowExecutionRequest, DeleteWorkflowExecutionResponse,
813
+ |r| {
814
+ let labels = AttachMetricLabels::namespace(r.get_ref().namespace.clone());
815
+ r.extensions_mut().insert(labels);
816
+ }
817
+ );
818
+ (add_or_update_remote_cluster, AddOrUpdateRemoteClusterRequest, AddOrUpdateRemoteClusterResponse);
819
+ (remove_remote_cluster, RemoveRemoteClusterRequest, RemoveRemoteClusterResponse);
820
+ (describe_cluster, DescribeClusterRequest, DescribeClusterResponse);
821
+ (list_clusters, ListClustersRequest, ListClustersResponse);
822
+ (list_cluster_members, ListClusterMembersRequest, ListClusterMembersResponse);
823
+ }
824
+
825
+ proxier! {
826
+ TestService; ALL_IMPLEMENTED_TEST_SERVICE_RPCS; TestServiceClient; test_client;
827
+ (lock_time_skipping, LockTimeSkippingRequest, LockTimeSkippingResponse);
828
+ (unlock_time_skipping, UnlockTimeSkippingRequest, UnlockTimeSkippingResponse);
829
+ (sleep, SleepRequest, SleepResponse);
830
+ (sleep_until, SleepUntilRequest, SleepResponse);
831
+ (unlock_time_skipping_with_sleep, SleepRequest, SleepResponse);
832
+ (get_current_time, (), GetCurrentTimeResponse);
833
+ }
834
+
835
+ proxier! {
836
+ HealthService; ALL_IMPLEMENTED_HEALTH_SERVICE_RPCS; HealthClient; health_client;
837
+ (check, HealthCheckRequest, HealthCheckResponse);
838
+ (watch, HealthCheckRequest, tonic::codec::Streaming<HealthCheckResponse>);
632
839
  }
633
840
 
634
841
  #[cfg(test)]
635
842
  mod tests {
636
843
  use super::*;
637
- use crate::{ClientOptionsBuilder, RetryClient, WorkflowServiceClientWithMetrics};
844
+ use crate::{ClientOptionsBuilder, RetryClient};
638
845
  use std::collections::HashSet;
639
- use temporal_sdk_core_protos::temporal::api::workflowservice::v1::ListNamespacesRequest;
846
+ use temporal_sdk_core_protos::temporal::api::{
847
+ operatorservice::v1::DeleteNamespaceRequest, workflowservice::v1::ListNamespacesRequest,
848
+ };
640
849
 
641
850
  // Just to help make sure some stuff compiles. Not run.
642
851
  #[allow(dead_code)]
@@ -645,23 +854,39 @@ mod tests {
645
854
  let raw_client = opts.connect_no_namespace(None, None).await.unwrap();
646
855
  let mut retry_client = RetryClient::new(raw_client, opts.retry_config);
647
856
 
648
- let the_request = ListNamespacesRequest::default();
649
- let fact = |c: &mut WorkflowServiceClientWithMetrics, req| {
650
- let mut c = c.clone();
857
+ let list_ns_req = ListNamespacesRequest::default();
858
+ let fact = |c: &mut RetryClient<_>, req| {
859
+ let mut c = c.workflow_client().clone();
651
860
  async move { c.list_namespaces(req).await }.boxed()
652
861
  };
653
862
  retry_client
654
- .do_call("whatever", fact, tonic::Request::new(the_request))
863
+ .call("whatever", fact, Request::new(list_ns_req.clone()))
864
+ .await
865
+ .unwrap();
866
+
867
+ // Operator svc method
868
+ let del_ns_req = DeleteNamespaceRequest::default();
869
+ let fact = |c: &mut RetryClient<_>, req| {
870
+ let mut c = c.operator_client().clone();
871
+ async move { c.delete_namespace(req).await }.boxed()
872
+ };
873
+ retry_client
874
+ .call("whatever", fact, Request::new(del_ns_req.clone()))
875
+ .await
876
+ .unwrap();
877
+
878
+ // Verify calling through traits works
879
+ retry_client.list_namespaces(list_ns_req).await.unwrap();
880
+ retry_client.delete_namespace(del_ns_req).await.unwrap();
881
+ retry_client.get_current_time(()).await.unwrap();
882
+ retry_client
883
+ .check(HealthCheckRequest::default())
655
884
  .await
656
885
  .unwrap();
657
886
  }
658
887
 
659
- #[test]
660
- fn verify_all_methods_implemented() {
661
- // This is less work than trying to hook into the codegen process
662
- let proto_def =
663
- include_str!("../../protos/api_upstream/temporal/api/workflowservice/v1/service.proto");
664
- let methods: Vec<_> = proto_def
888
+ fn verify_methods(proto_def_str: &str, impl_list: &[&str]) {
889
+ let methods: Vec<_> = proto_def_str
665
890
  .lines()
666
891
  .map(|l| l.trim())
667
892
  .filter(|l| l.starts_with("rpc"))
@@ -670,17 +895,38 @@ mod tests {
670
895
  (&stripped[..stripped.find('(').unwrap()]).trim()
671
896
  })
672
897
  .collect();
673
- let no_underscores: HashSet<_> = ALL_IMPLEMENTED_RPCS
674
- .iter()
675
- .map(|x| x.replace('_', ""))
676
- .collect();
898
+ let no_underscores: HashSet<_> = impl_list.iter().map(|x| x.replace('_', "")).collect();
677
899
  for method in methods {
678
900
  if !no_underscores.contains(&method.to_lowercase()) {
679
- panic!(
680
- "WorkflowService RPC method {} is not implemented by raw client",
681
- method
682
- )
901
+ panic!("RPC method {} is not implemented by raw client", method)
683
902
  }
684
903
  }
685
904
  }
905
+ #[test]
906
+ fn verify_all_workflow_service_methods_implemented() {
907
+ // This is less work than trying to hook into the codegen process
908
+ let proto_def =
909
+ include_str!("../../protos/api_upstream/temporal/api/workflowservice/v1/service.proto");
910
+ verify_methods(proto_def, ALL_IMPLEMENTED_WORKFLOW_SERVICE_RPCS);
911
+ }
912
+
913
+ #[test]
914
+ fn verify_all_operator_service_methods_implemented() {
915
+ let proto_def =
916
+ include_str!("../../protos/api_upstream/temporal/api/operatorservice/v1/service.proto");
917
+ verify_methods(proto_def, ALL_IMPLEMENTED_OPERATOR_SERVICE_RPCS);
918
+ }
919
+
920
+ #[test]
921
+ fn verify_all_test_service_methods_implemented() {
922
+ let proto_def =
923
+ include_str!("../../protos/testsrv_upstream/temporal/api/testservice/v1/service.proto");
924
+ verify_methods(proto_def, ALL_IMPLEMENTED_TEST_SERVICE_RPCS);
925
+ }
926
+
927
+ #[test]
928
+ fn verify_all_health_service_methods_implemented() {
929
+ let proto_def = include_str!("../../protos/grpc/health/v1/health.proto");
930
+ verify_methods(proto_def, ALL_IMPLEMENTED_HEALTH_SERVICE_RPCS);
931
+ }
686
932
  }