@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.
- package/Cargo.lock +786 -54
- package/Cargo.toml +2 -2
- package/common.js +7 -3
- package/index.d.ts +110 -3
- package/index.js +2 -6
- package/package.json +3 -3
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/releases/x86_64-apple-darwin/index.node +0 -0
- package/releases/x86_64-pc-windows-msvc/index.node +0 -0
- package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
- package/scripts/build.js +4 -3
- package/sdk-core/.buildkite/docker/Dockerfile +2 -1
- package/sdk-core/ARCHITECTURE.md +2 -2
- package/sdk-core/README.md +12 -0
- package/sdk-core/bridge-ffi/Cargo.toml +2 -2
- package/sdk-core/client/Cargo.toml +6 -4
- package/sdk-core/client/src/lib.rs +338 -215
- package/sdk-core/client/src/raw.rs +352 -106
- package/sdk-core/client/src/retry.rs +159 -133
- package/sdk-core/client/src/workflow_handle/mod.rs +1 -1
- package/sdk-core/core/Cargo.toml +18 -9
- package/sdk-core/core/src/core_tests/activity_tasks.rs +63 -23
- package/sdk-core/core/src/core_tests/child_workflows.rs +125 -3
- package/sdk-core/core/src/core_tests/local_activities.rs +6 -6
- package/sdk-core/core/src/core_tests/workers.rs +3 -2
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +70 -2
- package/sdk-core/core/src/ephemeral_server/mod.rs +499 -0
- package/sdk-core/core/src/lib.rs +60 -26
- package/sdk-core/core/src/pollers/poll_buffer.rs +4 -4
- package/sdk-core/core/src/replay/mod.rs +3 -3
- package/sdk-core/core/src/retry_logic.rs +10 -9
- package/sdk-core/core/src/telemetry/mod.rs +10 -7
- package/sdk-core/core/src/test_help/mod.rs +18 -8
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +10 -10
- package/sdk-core/core/src/worker/activities/local_activities.rs +13 -13
- package/sdk-core/core/src/worker/activities.rs +6 -12
- package/sdk-core/core/src/worker/client.rs +193 -64
- package/sdk-core/core/src/worker/mod.rs +14 -19
- package/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -0
- package/sdk-core/core/src/worker/workflow/history_update.rs +5 -5
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +133 -85
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +3 -2
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +160 -105
- package/sdk-core/core/src/worker/workflow/managed_run.rs +2 -1
- package/sdk-core/core/src/worker/workflow/mod.rs +59 -58
- package/sdk-core/core/src/worker/workflow/run_cache.rs +5 -3
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +7 -5
- package/sdk-core/core-api/Cargo.toml +2 -2
- package/sdk-core/core-api/src/errors.rs +3 -11
- package/sdk-core/core-api/src/worker.rs +7 -0
- package/sdk-core/protos/api_upstream/.buildkite/Dockerfile +1 -1
- package/sdk-core/protos/api_upstream/.github/CODEOWNERS +1 -1
- package/sdk-core/protos/api_upstream/.github/PULL_REQUEST_TEMPLATE.md +2 -6
- package/sdk-core/protos/api_upstream/.github/workflows/trigger-api-go-update.yml +29 -0
- package/sdk-core/protos/api_upstream/Makefile +2 -2
- package/sdk-core/protos/api_upstream/buf.yaml +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +86 -0
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +26 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +46 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +7 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +14 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +51 -0
- package/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +18 -0
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +57 -1
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +1 -3
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +4 -2
- package/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +11 -0
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +23 -0
- package/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +46 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +172 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +30 -0
- package/sdk-core/protos/grpc/health/v1/health.proto +63 -0
- package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +18 -15
- package/sdk-core/protos/testsrv_upstream/Makefile +80 -0
- package/sdk-core/protos/testsrv_upstream/api-linter.yaml +38 -0
- package/sdk-core/protos/testsrv_upstream/buf.yaml +13 -0
- package/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +141 -0
- package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +63 -0
- package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +90 -0
- package/sdk-core/sdk/Cargo.toml +2 -2
- package/sdk-core/sdk/src/lib.rs +2 -2
- package/sdk-core/sdk/src/workflow_context/options.rs +36 -8
- package/sdk-core/sdk/src/workflow_context.rs +30 -6
- package/sdk-core/sdk/src/workflow_future.rs +4 -4
- package/sdk-core/sdk-core-protos/Cargo.toml +5 -5
- package/sdk-core/sdk-core-protos/build.rs +9 -1
- package/sdk-core/sdk-core-protos/src/history_builder.rs +6 -1
- package/sdk-core/sdk-core-protos/src/lib.rs +93 -32
- package/sdk-core/test-utils/Cargo.toml +3 -3
- package/sdk-core/test-utils/src/canned_histories.rs +58 -0
- package/sdk-core/test-utils/src/lib.rs +14 -10
- package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +141 -0
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +55 -5
- package/sdk-core/tests/integ_tests/polling_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/queries_tests.rs +4 -4
- package/sdk-core/tests/integ_tests/visibility_tests.rs +93 -0
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +93 -10
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +14 -14
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +12 -12
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +12 -1
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +3 -3
- package/sdk-core/tests/integ_tests/workflow_tests.rs +19 -4
- package/sdk-core/tests/load_tests.rs +2 -1
- package/sdk-core/tests/main.rs +10 -0
- package/src/conversions.rs +138 -91
- package/src/helpers.rs +190 -0
- package/src/lib.rs +10 -912
- package/src/runtime.rs +436 -0
- package/src/testing.rs +67 -0
- 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::
|
|
12
|
-
|
|
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
|
|
28
|
-
fn
|
|
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
|
-
|
|
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
|
|
56
|
+
callfn(self, req).await
|
|
45
57
|
}
|
|
46
58
|
}
|
|
59
|
+
}
|
|
47
60
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
70
|
+
fn workflow_client(&mut self) -> &mut WorkflowServiceClient<Self::SvcType> {
|
|
71
|
+
self.get_client_mut().workflow_client()
|
|
72
|
+
}
|
|
60
73
|
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
82
|
+
fn health_client(&mut self) -> &mut HealthClient<Self::SvcType> {
|
|
83
|
+
self.get_client_mut().health_client()
|
|
95
84
|
}
|
|
96
85
|
|
|
97
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
104
|
-
|
|
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
|
-
|
|
109
|
-
|
|
122
|
+
fn operator_client(&mut self) -> &mut OperatorServiceClient<Self::SvcType> {
|
|
123
|
+
self.operator_svc_mut()
|
|
124
|
+
}
|
|
110
125
|
|
|
111
|
-
|
|
112
|
-
|
|
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: &
|
|
184
|
+
fn req_cloner<T: Clone>(cloneme: &Request<T>) -> Request<T> {
|
|
120
185
|
let msg = cloneme.get_ref().clone();
|
|
121
|
-
let mut new_req =
|
|
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.
|
|
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:
|
|
171
|
-
#[doc = concat!("See [
|
|
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
|
|
175
|
-
) -> BoxFuture<Result<tonic::Response
|
|
273
|
+
request: impl tonic::IntoRequest<$req>,
|
|
274
|
+
) -> BoxFuture<Result<tonic::Response<$resp>, tonic::Status>> {
|
|
176
275
|
#[allow(unused_mut)]
|
|
177
|
-
let fact = |c: &mut
|
|
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.
|
|
281
|
+
self.call(stringify!($method), fact, request.into_request())
|
|
183
282
|
}
|
|
184
283
|
};
|
|
185
284
|
}
|
|
186
285
|
macro_rules! proxier {
|
|
187
|
-
( $
|
|
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
|
|
190
|
-
/// Trait version of the generated
|
|
191
|
-
///
|
|
192
|
-
pub trait
|
|
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
|
|
844
|
+
use crate::{ClientOptionsBuilder, RetryClient};
|
|
638
845
|
use std::collections::HashSet;
|
|
639
|
-
use temporal_sdk_core_protos::temporal::api::
|
|
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
|
|
649
|
-
let fact = |c: &mut
|
|
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
|
-
.
|
|
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
|
-
|
|
660
|
-
|
|
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<_> =
|
|
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
|
}
|