squads_temporal_client/
raw.rs

1//! We need a way to trait-ify the raw grpc client because there is no other way to get the
2//! information we need via interceptors. This module contains the necessary stuff to make that
3//! happen.
4
5use crate::{
6    Client, ConfiguredClient, InterceptedMetricsSvc, LONG_POLL_TIMEOUT, RequestExt, RetryClient,
7    SharedReplaceableClient, TEMPORAL_NAMESPACE_HEADER_KEY, TemporalServiceClient,
8    metrics::{namespace_kv, task_queue_kv},
9    raw::sealed::RawClientLike,
10    worker_registry::{Slot, SlotManager},
11};
12use futures_util::{FutureExt, TryFutureExt, future::BoxFuture};
13use std::sync::Arc;
14use temporal_sdk_core_api::telemetry::metrics::MetricKeyValue;
15use temporal_sdk_core_protos::{
16    grpc::health::v1::{health_client::HealthClient, *},
17    temporal::api::{
18        cloud::cloudservice::{v1 as cloudreq, v1::cloud_service_client::CloudServiceClient},
19        operatorservice::v1::{operator_service_client::OperatorServiceClient, *},
20        taskqueue::v1::TaskQueue,
21        testservice::v1::{test_service_client::TestServiceClient, *},
22        workflowservice::v1::{workflow_service_client::WorkflowServiceClient, *},
23    },
24};
25use tonic::{
26    Request, Response, Status,
27    body::Body,
28    client::GrpcService,
29    metadata::{AsciiMetadataValue, KeyAndValueRef},
30};
31
32pub(super) mod sealed {
33    use super::*;
34
35    /// Something that has access to the raw grpc services
36    #[async_trait::async_trait]
37    pub trait RawClientLike: Send {
38        type SvcType: Send + Sync + Clone + 'static;
39
40        /// Return a mutable ref to the workflow service client instance
41        fn workflow_client_mut(&mut self) -> &mut WorkflowServiceClient<Self::SvcType>;
42
43        /// Return a mutable ref to the operator service client instance
44        fn operator_client_mut(&mut self) -> &mut OperatorServiceClient<Self::SvcType>;
45
46        /// Return a mutable ref to the cloud service client instance
47        fn cloud_client_mut(&mut self) -> &mut CloudServiceClient<Self::SvcType>;
48
49        /// Return a mutable ref to the test service client instance
50        fn test_client_mut(&mut self) -> &mut TestServiceClient<Self::SvcType>;
51
52        /// Return a mutable ref to the health service client instance
53        fn health_client_mut(&mut self) -> &mut HealthClient<Self::SvcType>;
54
55        /// Return a registry with workers using this client instance
56        fn get_workers_info(&self) -> Option<Arc<SlotManager>>;
57
58        async fn call<F, Req, Resp>(
59            &mut self,
60            _call_name: &'static str,
61            mut callfn: F,
62            req: Request<Req>,
63        ) -> Result<Response<Resp>, Status>
64        where
65            Req: Clone + Unpin + Send + Sync + 'static,
66            F: FnMut(&mut Self, Request<Req>) -> BoxFuture<'static, Result<Response<Resp>, Status>>,
67            F: Send + Sync + Unpin + 'static,
68        {
69            callfn(self, req).await
70        }
71    }
72}
73
74#[async_trait::async_trait]
75impl<RC, T> RawClientLike for RetryClient<RC>
76where
77    RC: RawClientLike<SvcType = T> + 'static,
78    T: Send + Sync + Clone + 'static,
79{
80    type SvcType = T;
81
82    fn workflow_client_mut(&mut self) -> &mut WorkflowServiceClient<Self::SvcType> {
83        self.get_client_mut().workflow_client_mut()
84    }
85
86    fn operator_client_mut(&mut self) -> &mut OperatorServiceClient<Self::SvcType> {
87        self.get_client_mut().operator_client_mut()
88    }
89
90    fn cloud_client_mut(&mut self) -> &mut CloudServiceClient<Self::SvcType> {
91        self.get_client_mut().cloud_client_mut()
92    }
93
94    fn test_client_mut(&mut self) -> &mut TestServiceClient<Self::SvcType> {
95        self.get_client_mut().test_client_mut()
96    }
97
98    fn health_client_mut(&mut self) -> &mut HealthClient<Self::SvcType> {
99        self.get_client_mut().health_client_mut()
100    }
101
102    fn get_workers_info(&self) -> Option<Arc<SlotManager>> {
103        self.get_client().get_workers_info()
104    }
105
106    async fn call<F, Req, Resp>(
107        &mut self,
108        call_name: &'static str,
109        mut callfn: F,
110        mut req: Request<Req>,
111    ) -> Result<Response<Resp>, Status>
112    where
113        Req: Clone + Unpin + Send + Sync + 'static,
114        F: FnMut(&mut Self, Request<Req>) -> BoxFuture<'static, Result<Response<Resp>, Status>>,
115        F: Send + Sync + Unpin + 'static,
116    {
117        let info = self.get_call_info(call_name, Some(&req));
118        req.extensions_mut().insert(info.call_type);
119        if info.call_type.is_long() {
120            req.set_default_timeout(LONG_POLL_TIMEOUT);
121        }
122        let fact = || {
123            let req_clone = req_cloner(&req);
124            callfn(self, req_clone)
125        };
126        let res = Self::make_future_retry(info, fact);
127        res.map_err(|(e, _attempt)| e).map_ok(|x| x.0).await
128    }
129}
130
131#[async_trait::async_trait]
132impl<RC, T> RawClientLike for SharedReplaceableClient<RC>
133where
134    RC: RawClientLike<SvcType = T> + Clone + Sync + 'static,
135    T: Send + Sync + Clone + 'static,
136{
137    type SvcType = T;
138
139    fn workflow_client_mut(&mut self) -> &mut WorkflowServiceClient<Self::SvcType> {
140        self.inner_mut_refreshed().workflow_client_mut()
141    }
142
143    fn operator_client_mut(&mut self) -> &mut OperatorServiceClient<Self::SvcType> {
144        self.inner_mut_refreshed().operator_client_mut()
145    }
146
147    fn cloud_client_mut(&mut self) -> &mut CloudServiceClient<Self::SvcType> {
148        self.inner_mut_refreshed().cloud_client_mut()
149    }
150
151    fn test_client_mut(&mut self) -> &mut TestServiceClient<Self::SvcType> {
152        self.inner_mut_refreshed().test_client_mut()
153    }
154
155    fn health_client_mut(&mut self) -> &mut HealthClient<Self::SvcType> {
156        self.inner_mut_refreshed().health_client_mut()
157    }
158
159    fn get_workers_info(&self) -> Option<Arc<SlotManager>> {
160        self.inner_cow().get_workers_info()
161    }
162}
163
164impl<T> RawClientLike for TemporalServiceClient<T>
165where
166    T: Send + Sync + Clone + 'static,
167    T: GrpcService<Body> + Send + Clone + 'static,
168    T::ResponseBody: tonic::codegen::Body<Data = tonic::codegen::Bytes> + Send + 'static,
169    T::Error: Into<tonic::codegen::StdError>,
170    <T::ResponseBody as tonic::codegen::Body>::Error: Into<tonic::codegen::StdError> + Send,
171{
172    type SvcType = T;
173
174    fn workflow_client_mut(&mut self) -> &mut WorkflowServiceClient<Self::SvcType> {
175        self.workflow_svc_mut()
176    }
177
178    fn operator_client_mut(&mut self) -> &mut OperatorServiceClient<Self::SvcType> {
179        self.operator_svc_mut()
180    }
181
182    fn cloud_client_mut(&mut self) -> &mut CloudServiceClient<Self::SvcType> {
183        self.cloud_svc_mut()
184    }
185
186    fn test_client_mut(&mut self) -> &mut TestServiceClient<Self::SvcType> {
187        self.test_svc_mut()
188    }
189
190    fn health_client_mut(&mut self) -> &mut HealthClient<Self::SvcType> {
191        self.health_svc_mut()
192    }
193
194    fn get_workers_info(&self) -> Option<Arc<SlotManager>> {
195        None
196    }
197}
198
199impl<T> RawClientLike for ConfiguredClient<TemporalServiceClient<T>>
200where
201    T: Send + Sync + Clone + 'static,
202    T: GrpcService<Body> + Send + Clone + 'static,
203    T::ResponseBody: tonic::codegen::Body<Data = tonic::codegen::Bytes> + Send + 'static,
204    T::Error: Into<tonic::codegen::StdError>,
205    <T::ResponseBody as tonic::codegen::Body>::Error: Into<tonic::codegen::StdError> + Send,
206{
207    type SvcType = T;
208
209    fn workflow_client_mut(&mut self) -> &mut WorkflowServiceClient<Self::SvcType> {
210        self.client.workflow_client_mut()
211    }
212
213    fn operator_client_mut(&mut self) -> &mut OperatorServiceClient<Self::SvcType> {
214        self.client.operator_client_mut()
215    }
216
217    fn cloud_client_mut(&mut self) -> &mut CloudServiceClient<Self::SvcType> {
218        self.client.cloud_client_mut()
219    }
220
221    fn test_client_mut(&mut self) -> &mut TestServiceClient<Self::SvcType> {
222        self.client.test_client_mut()
223    }
224
225    fn health_client_mut(&mut self) -> &mut HealthClient<Self::SvcType> {
226        self.client.health_client_mut()
227    }
228
229    fn get_workers_info(&self) -> Option<Arc<SlotManager>> {
230        Some(self.workers())
231    }
232}
233
234impl RawClientLike for Client {
235    type SvcType = InterceptedMetricsSvc;
236
237    fn workflow_client_mut(&mut self) -> &mut WorkflowServiceClient<Self::SvcType> {
238        self.inner.workflow_client_mut()
239    }
240
241    fn operator_client_mut(&mut self) -> &mut OperatorServiceClient<Self::SvcType> {
242        self.inner.operator_client_mut()
243    }
244
245    fn cloud_client_mut(&mut self) -> &mut CloudServiceClient<Self::SvcType> {
246        self.inner.cloud_client_mut()
247    }
248
249    fn test_client_mut(&mut self) -> &mut TestServiceClient<Self::SvcType> {
250        self.inner.test_client_mut()
251    }
252
253    fn health_client_mut(&mut self) -> &mut HealthClient<Self::SvcType> {
254        self.inner.health_client_mut()
255    }
256
257    fn get_workers_info(&self) -> Option<Arc<SlotManager>> {
258        self.inner.get_workers_info()
259    }
260}
261
262/// Helper for cloning a tonic request as long as the inner message may be cloned.
263fn req_cloner<T: Clone>(cloneme: &Request<T>) -> Request<T> {
264    let msg = cloneme.get_ref().clone();
265    let mut new_req = Request::new(msg);
266    let new_met = new_req.metadata_mut();
267    for kv in cloneme.metadata().iter() {
268        match kv {
269            KeyAndValueRef::Ascii(k, v) => {
270                new_met.insert(k, v.clone());
271            }
272            KeyAndValueRef::Binary(k, v) => {
273                new_met.insert_bin(k, v.clone());
274            }
275        }
276    }
277    *new_req.extensions_mut() = cloneme.extensions().clone();
278    new_req
279}
280
281#[derive(Clone, Debug)]
282pub(super) struct AttachMetricLabels {
283    pub(super) labels: Vec<MetricKeyValue>,
284}
285impl AttachMetricLabels {
286    pub(super) fn new(kvs: impl Into<Vec<MetricKeyValue>>) -> Self {
287        Self { labels: kvs.into() }
288    }
289    pub(super) fn namespace(ns: impl Into<String>) -> Self {
290        AttachMetricLabels::new(vec![namespace_kv(ns.into())])
291    }
292    pub(super) fn task_q(&mut self, tq: Option<TaskQueue>) -> &mut Self {
293        if let Some(tq) = tq {
294            self.task_q_str(tq.name);
295        }
296        self
297    }
298    pub(super) fn task_q_str(&mut self, tq: impl Into<String>) -> &mut Self {
299        self.labels.push(task_queue_kv(tq.into()));
300        self
301    }
302}
303
304/// A request extension that, when set, should make the [RetryClient] consider this call to be a
305/// [super::retry::CallType::UserLongPoll]
306#[derive(Copy, Clone, Debug)]
307pub(super) struct IsUserLongPoll;
308
309// Blanket impl the trait for all raw-client-like things. Since the trait default-implements
310// everything, there's nothing to actually implement.
311impl<RC, T> WorkflowService for RC
312where
313    RC: RawClientLike<SvcType = T>,
314    T: GrpcService<Body> + Send + Clone + 'static,
315    T::ResponseBody: tonic::codegen::Body<Data = tonic::codegen::Bytes> + Send + 'static,
316    T::Error: Into<tonic::codegen::StdError>,
317    T::Future: Send,
318    <T::ResponseBody as tonic::codegen::Body>::Error: Into<tonic::codegen::StdError> + Send,
319{
320}
321impl<RC, T> OperatorService for RC
322where
323    RC: RawClientLike<SvcType = T>,
324    T: GrpcService<Body> + Send + Clone + 'static,
325    T::ResponseBody: tonic::codegen::Body<Data = tonic::codegen::Bytes> + Send + 'static,
326    T::Error: Into<tonic::codegen::StdError>,
327    T::Future: Send,
328    <T::ResponseBody as tonic::codegen::Body>::Error: Into<tonic::codegen::StdError> + Send,
329{
330}
331impl<RC, T> CloudService for RC
332where
333    RC: RawClientLike<SvcType = T>,
334    T: GrpcService<Body> + Send + Clone + 'static,
335    T::ResponseBody: tonic::codegen::Body<Data = tonic::codegen::Bytes> + Send + 'static,
336    T::Error: Into<tonic::codegen::StdError>,
337    T::Future: Send,
338    <T::ResponseBody as tonic::codegen::Body>::Error: Into<tonic::codegen::StdError> + Send,
339{
340}
341impl<RC, T> TestService for RC
342where
343    RC: RawClientLike<SvcType = T>,
344    T: GrpcService<Body> + Send + Clone + 'static,
345    T::ResponseBody: tonic::codegen::Body<Data = tonic::codegen::Bytes> + Send + 'static,
346    T::Error: Into<tonic::codegen::StdError>,
347    T::Future: Send,
348    <T::ResponseBody as tonic::codegen::Body>::Error: Into<tonic::codegen::StdError> + Send,
349{
350}
351impl<RC, T> HealthService for RC
352where
353    RC: RawClientLike<SvcType = T>,
354    T: GrpcService<Body> + Send + Clone + 'static,
355    T::ResponseBody: tonic::codegen::Body<Data = tonic::codegen::Bytes> + Send + 'static,
356    T::Error: Into<tonic::codegen::StdError>,
357    T::Future: Send,
358    <T::ResponseBody as tonic::codegen::Body>::Error: Into<tonic::codegen::StdError> + Send,
359{
360}
361
362/// Helps re-declare gRPC client methods
363///
364/// There are two forms:
365///
366/// * The first takes a closure that can modify the request. This is only called once, before the
367///   actual rpc call is made, and before determinations are made about the kind of call (long poll
368///   or not) and retry policy.
369/// * The second takes three closures. The first can modify the request like in the first form.
370///   The second can modify the request and return a value, and is called right before every call
371///   (including on retries). The third is called with the response to the call after it resolves.
372macro_rules! proxy {
373    ($client_type:tt, $client_meth:ident, $method:ident, $req:ty, $resp:ty $(, $closure:expr)?) => {
374        #[doc = concat!("See [", stringify!($client_type), "::", stringify!($method), "]")]
375        fn $method(
376            &mut self,
377            request: impl tonic::IntoRequest<$req>,
378        ) -> BoxFuture<'_, Result<tonic::Response<$resp>, tonic::Status>> {
379            #[allow(unused_mut)]
380            let mut as_req = request.into_request();
381            $( type_closure_arg(&mut as_req, $closure); )*
382            #[allow(unused_mut)]
383            let fact = |c: &mut Self, mut req: tonic::Request<$req>| {
384                let mut c = c.$client_meth().clone();
385                async move { c.$method(req).await }.boxed()
386            };
387            self.call(stringify!($method), fact, as_req)
388        }
389    };
390    ($client_type:tt, $client_meth:ident, $method:ident, $req:ty, $resp:ty,
391     $closure_request:expr, $closure_before:expr, $closure_after:expr) => {
392        #[doc = concat!("See [", stringify!($client_type), "::", stringify!($method), "]")]
393        fn $method(
394            &mut self,
395            request: impl tonic::IntoRequest<$req>,
396        ) -> BoxFuture<'_, Result<tonic::Response<$resp>, tonic::Status>> {
397            #[allow(unused_mut)]
398            let mut as_req = request.into_request();
399            type_closure_arg(&mut as_req, $closure_request);
400            #[allow(unused_mut)]
401            let fact = |c: &mut Self, mut req: tonic::Request<$req>| {
402                let data = type_closure_two_arg(&mut req, c.get_workers_info().unwrap(),
403                                                $closure_before);
404                let mut c = c.$client_meth().clone();
405                async move {
406                    type_closure_two_arg(c.$method(req).await, data, $closure_after)
407                }.boxed()
408            };
409            self.call(stringify!($method), fact, as_req)
410        }
411    };
412}
413macro_rules! proxier {
414    ( $trait_name:ident; $impl_list_name:ident; $client_type:tt; $client_meth:ident;
415      $(($method:ident, $req:ty, $resp:ty
416         $(, $closure:expr $(, $closure_before:expr, $closure_after:expr)?)? );)* ) => {
417        #[cfg(test)]
418        const $impl_list_name: &'static [&'static str] = &[$(stringify!($method)),*];
419        /// Trait version of the generated client with modifications to attach appropriate metric
420        /// labels or whatever else to requests
421        pub trait $trait_name: RawClientLike
422        where
423            // Yo this is wild
424            <Self as RawClientLike>::SvcType: GrpcService<Body> + Send + Clone + 'static,
425            <<Self as RawClientLike>::SvcType as GrpcService<Body>>::ResponseBody:
426                tonic::codegen::Body<Data = tonic::codegen::Bytes> + Send + 'static,
427            <<Self as RawClientLike>::SvcType as GrpcService<Body>>::Error:
428                Into<tonic::codegen::StdError>,
429            <<Self as RawClientLike>::SvcType as GrpcService<Body>>::Future: Send,
430            <<<Self as RawClientLike>::SvcType as GrpcService<Body>>::ResponseBody
431                as tonic::codegen::Body>::Error: Into<tonic::codegen::StdError> + Send,
432        {
433            $(
434               proxy!($client_type, $client_meth, $method, $req, $resp
435                      $(,$closure $(,$closure_before, $closure_after)*)*);
436            )*
437        }
438    };
439}
440
441macro_rules! namespaced_request {
442    ($req:ident) => {{
443        let ns_str = $req.get_ref().namespace.clone();
444        // Attach namespace header
445        $req.metadata_mut().insert(
446            TEMPORAL_NAMESPACE_HEADER_KEY,
447            ns_str.parse().unwrap_or_else(|e| {
448                warn!("Unable to parse namespace for header: {e:?}");
449                AsciiMetadataValue::from_static("")
450            }),
451        );
452        // Init metric labels
453        AttachMetricLabels::namespace(ns_str)
454    }};
455}
456
457// Nice little trick to avoid the callsite asking to type the closure parameter
458fn type_closure_arg<T, R>(arg: T, f: impl FnOnce(T) -> R) -> R {
459    f(arg)
460}
461
462fn type_closure_two_arg<T, R, S>(arg1: R, arg2: T, f: impl FnOnce(R, T) -> S) -> S {
463    f(arg1, arg2)
464}
465
466proxier! {
467    WorkflowService; ALL_IMPLEMENTED_WORKFLOW_SERVICE_RPCS; WorkflowServiceClient; workflow_client_mut;
468    (
469        register_namespace,
470        RegisterNamespaceRequest,
471        RegisterNamespaceResponse,
472        |r| {
473            let labels = namespaced_request!(r);
474            r.extensions_mut().insert(labels);
475        }
476    );
477    (
478        describe_namespace,
479        DescribeNamespaceRequest,
480        DescribeNamespaceResponse,
481        |r| {
482            let labels = namespaced_request!(r);
483            r.extensions_mut().insert(labels);
484        }
485    );
486    (
487        list_namespaces,
488        ListNamespacesRequest,
489        ListNamespacesResponse
490    );
491    (
492        update_namespace,
493        UpdateNamespaceRequest,
494        UpdateNamespaceResponse,
495        |r| {
496            let labels = namespaced_request!(r);
497            r.extensions_mut().insert(labels);
498        }
499    );
500    (
501        deprecate_namespace,
502        DeprecateNamespaceRequest,
503        DeprecateNamespaceResponse,
504        |r| {
505            let labels = namespaced_request!(r);
506            r.extensions_mut().insert(labels);
507        }
508    );
509    (
510        start_workflow_execution,
511        StartWorkflowExecutionRequest,
512        StartWorkflowExecutionResponse,
513        |r| {
514            let mut labels = namespaced_request!(r);
515            labels.task_q(r.get_ref().task_queue.clone());
516            r.extensions_mut().insert(labels);
517        },
518        |r, workers| {
519            let mut slot: Option<Box<dyn Slot + Send>> = None;
520            let req_mut = r.get_mut();
521            if req_mut.request_eager_execution {
522                let namespace = req_mut.namespace.clone();
523                let task_queue = req_mut.task_queue.as_ref()
524                                    .map(|tq| tq.name.clone()).unwrap_or_default();
525                match workers.try_reserve_wft_slot(namespace, task_queue) {
526                    Some(s) => slot = Some(s),
527                    None => req_mut.request_eager_execution = false
528                }
529            }
530            slot
531        },
532        |resp, slot| {
533            if let Some(mut s) = slot
534                && let Ok(response) = resp.as_ref()
535                    && let Some(task) = response.get_ref().clone().eager_workflow_task
536                        && let Err(e) = s.schedule_wft(task) {
537                            // This is a latency issue, i.e., the client does not need to handle
538                            //  this error, because the WFT will be retried after a timeout.
539                            warn!(details = ?e, "Eager workflow task rejected by worker.");
540                        }
541            resp
542        }
543    );
544    (
545        get_workflow_execution_history,
546        GetWorkflowExecutionHistoryRequest,
547        GetWorkflowExecutionHistoryResponse,
548        |r| {
549            let labels = namespaced_request!(r);
550            r.extensions_mut().insert(labels);
551            if r.get_ref().wait_new_event {
552                r.extensions_mut().insert(IsUserLongPoll);
553            }
554        }
555    );
556    (
557        get_workflow_execution_history_reverse,
558        GetWorkflowExecutionHistoryReverseRequest,
559        GetWorkflowExecutionHistoryReverseResponse,
560        |r| {
561            let labels = namespaced_request!(r);
562            r.extensions_mut().insert(labels);
563        }
564    );
565    (
566        poll_workflow_task_queue,
567        PollWorkflowTaskQueueRequest,
568        PollWorkflowTaskQueueResponse,
569        |r| {
570            let mut labels = namespaced_request!(r);
571            labels.task_q(r.get_ref().task_queue.clone());
572            r.extensions_mut().insert(labels);
573        }
574    );
575    (
576        respond_workflow_task_completed,
577        RespondWorkflowTaskCompletedRequest,
578        RespondWorkflowTaskCompletedResponse,
579        |r| {
580            let labels = namespaced_request!(r);
581            r.extensions_mut().insert(labels);
582        }
583    );
584    (
585        respond_workflow_task_failed,
586        RespondWorkflowTaskFailedRequest,
587        RespondWorkflowTaskFailedResponse,
588        |r| {
589            let labels = namespaced_request!(r);
590            r.extensions_mut().insert(labels);
591        }
592    );
593    (
594        poll_activity_task_queue,
595        PollActivityTaskQueueRequest,
596        PollActivityTaskQueueResponse,
597        |r| {
598            let mut labels = namespaced_request!(r);
599            labels.task_q(r.get_ref().task_queue.clone());
600            r.extensions_mut().insert(labels);
601        }
602    );
603    (
604        record_activity_task_heartbeat,
605        RecordActivityTaskHeartbeatRequest,
606        RecordActivityTaskHeartbeatResponse,
607        |r| {
608            let labels = namespaced_request!(r);
609            r.extensions_mut().insert(labels);
610        }
611    );
612    (
613        record_activity_task_heartbeat_by_id,
614        RecordActivityTaskHeartbeatByIdRequest,
615        RecordActivityTaskHeartbeatByIdResponse,
616        |r| {
617            let labels = namespaced_request!(r);
618            r.extensions_mut().insert(labels);
619        }
620    );
621    (
622        respond_activity_task_completed,
623        RespondActivityTaskCompletedRequest,
624        RespondActivityTaskCompletedResponse,
625        |r| {
626            let labels = namespaced_request!(r);
627            r.extensions_mut().insert(labels);
628        }
629    );
630    (
631        respond_activity_task_completed_by_id,
632        RespondActivityTaskCompletedByIdRequest,
633        RespondActivityTaskCompletedByIdResponse,
634        |r| {
635            let labels = namespaced_request!(r);
636            r.extensions_mut().insert(labels);
637        }
638    );
639
640    (
641        respond_activity_task_failed,
642        RespondActivityTaskFailedRequest,
643        RespondActivityTaskFailedResponse,
644        |r| {
645            let labels = namespaced_request!(r);
646            r.extensions_mut().insert(labels);
647        }
648    );
649    (
650        respond_activity_task_failed_by_id,
651        RespondActivityTaskFailedByIdRequest,
652        RespondActivityTaskFailedByIdResponse,
653        |r| {
654            let labels = namespaced_request!(r);
655            r.extensions_mut().insert(labels);
656        }
657    );
658    (
659        respond_activity_task_canceled,
660        RespondActivityTaskCanceledRequest,
661        RespondActivityTaskCanceledResponse,
662        |r| {
663            let labels = namespaced_request!(r);
664            r.extensions_mut().insert(labels);
665        }
666    );
667    (
668        respond_activity_task_canceled_by_id,
669        RespondActivityTaskCanceledByIdRequest,
670        RespondActivityTaskCanceledByIdResponse,
671        |r| {
672            let labels = namespaced_request!(r);
673            r.extensions_mut().insert(labels);
674        }
675    );
676    (
677        request_cancel_workflow_execution,
678        RequestCancelWorkflowExecutionRequest,
679        RequestCancelWorkflowExecutionResponse,
680        |r| {
681            let labels = namespaced_request!(r);
682            r.extensions_mut().insert(labels);
683        }
684    );
685    (
686        signal_workflow_execution,
687        SignalWorkflowExecutionRequest,
688        SignalWorkflowExecutionResponse,
689        |r| {
690            let labels = namespaced_request!(r);
691            r.extensions_mut().insert(labels);
692        }
693    );
694    (
695        signal_with_start_workflow_execution,
696        SignalWithStartWorkflowExecutionRequest,
697        SignalWithStartWorkflowExecutionResponse,
698        |r| {
699            let mut labels = namespaced_request!(r);
700            labels.task_q(r.get_ref().task_queue.clone());
701            r.extensions_mut().insert(labels);
702        }
703    );
704    (
705        reset_workflow_execution,
706        ResetWorkflowExecutionRequest,
707        ResetWorkflowExecutionResponse,
708        |r| {
709            let labels = namespaced_request!(r);
710            r.extensions_mut().insert(labels);
711        }
712    );
713    (
714        terminate_workflow_execution,
715        TerminateWorkflowExecutionRequest,
716        TerminateWorkflowExecutionResponse,
717        |r| {
718            let labels = namespaced_request!(r);
719            r.extensions_mut().insert(labels);
720        }
721    );
722    (
723        delete_workflow_execution,
724        DeleteWorkflowExecutionRequest,
725        DeleteWorkflowExecutionResponse,
726        |r| {
727            let labels = namespaced_request!(r);
728            r.extensions_mut().insert(labels);
729        }
730    );
731    (
732        list_open_workflow_executions,
733        ListOpenWorkflowExecutionsRequest,
734        ListOpenWorkflowExecutionsResponse,
735        |r| {
736            let labels = namespaced_request!(r);
737            r.extensions_mut().insert(labels);
738        }
739    );
740    (
741        list_closed_workflow_executions,
742        ListClosedWorkflowExecutionsRequest,
743        ListClosedWorkflowExecutionsResponse,
744        |r| {
745            let labels = namespaced_request!(r);
746            r.extensions_mut().insert(labels);
747        }
748    );
749    (
750        list_workflow_executions,
751        ListWorkflowExecutionsRequest,
752        ListWorkflowExecutionsResponse,
753        |r| {
754            let labels = namespaced_request!(r);
755            r.extensions_mut().insert(labels);
756        }
757    );
758    (
759        list_archived_workflow_executions,
760        ListArchivedWorkflowExecutionsRequest,
761        ListArchivedWorkflowExecutionsResponse,
762        |r| {
763            let labels = namespaced_request!(r);
764            r.extensions_mut().insert(labels);
765        }
766    );
767    (
768        scan_workflow_executions,
769        ScanWorkflowExecutionsRequest,
770        ScanWorkflowExecutionsResponse,
771        |r| {
772            let labels = namespaced_request!(r);
773            r.extensions_mut().insert(labels);
774        }
775    );
776    (
777        count_workflow_executions,
778        CountWorkflowExecutionsRequest,
779        CountWorkflowExecutionsResponse,
780        |r| {
781            let labels = namespaced_request!(r);
782            r.extensions_mut().insert(labels);
783        }
784    );
785    (
786        create_workflow_rule,
787        CreateWorkflowRuleRequest,
788        CreateWorkflowRuleResponse,
789        |r| {
790            let labels = namespaced_request!(r);
791            r.extensions_mut().insert(labels);
792        }
793    );
794    (
795        describe_workflow_rule,
796        DescribeWorkflowRuleRequest,
797        DescribeWorkflowRuleResponse,
798        |r| {
799            let labels = namespaced_request!(r);
800            r.extensions_mut().insert(labels);
801        }
802    );
803    (
804        delete_workflow_rule,
805        DeleteWorkflowRuleRequest,
806        DeleteWorkflowRuleResponse,
807        |r| {
808            let labels = namespaced_request!(r);
809            r.extensions_mut().insert(labels);
810        }
811    );
812    (
813        list_workflow_rules,
814        ListWorkflowRulesRequest,
815        ListWorkflowRulesResponse,
816        |r| {
817            let labels = namespaced_request!(r);
818            r.extensions_mut().insert(labels);
819        }
820    );
821    (
822        trigger_workflow_rule,
823        TriggerWorkflowRuleRequest,
824        TriggerWorkflowRuleResponse,
825        |r| {
826            let labels = namespaced_request!(r);
827            r.extensions_mut().insert(labels);
828        }
829    );
830    (
831        get_search_attributes,
832        GetSearchAttributesRequest,
833        GetSearchAttributesResponse
834    );
835    (
836        respond_query_task_completed,
837        RespondQueryTaskCompletedRequest,
838        RespondQueryTaskCompletedResponse,
839        |r| {
840            let labels = namespaced_request!(r);
841            r.extensions_mut().insert(labels);
842        }
843    );
844    (
845        reset_sticky_task_queue,
846        ResetStickyTaskQueueRequest,
847        ResetStickyTaskQueueResponse,
848        |r| {
849            let labels = namespaced_request!(r);
850            r.extensions_mut().insert(labels);
851        }
852    );
853    (
854        query_workflow,
855        QueryWorkflowRequest,
856        QueryWorkflowResponse,
857        |r| {
858            let labels = namespaced_request!(r);
859            r.extensions_mut().insert(labels);
860        }
861    );
862    (
863        describe_workflow_execution,
864        DescribeWorkflowExecutionRequest,
865        DescribeWorkflowExecutionResponse,
866        |r| {
867            let labels = namespaced_request!(r);
868            r.extensions_mut().insert(labels);
869        }
870    );
871    (
872        describe_task_queue,
873        DescribeTaskQueueRequest,
874        DescribeTaskQueueResponse,
875        |r| {
876            let mut labels = namespaced_request!(r);
877            labels.task_q(r.get_ref().task_queue.clone());
878            r.extensions_mut().insert(labels);
879        }
880    );
881    (
882        get_cluster_info,
883        GetClusterInfoRequest,
884        GetClusterInfoResponse
885    );
886    (
887        get_system_info,
888        GetSystemInfoRequest,
889        GetSystemInfoResponse
890    );
891    (
892        list_task_queue_partitions,
893        ListTaskQueuePartitionsRequest,
894        ListTaskQueuePartitionsResponse,
895        |r| {
896            let mut labels = namespaced_request!(r);
897            labels.task_q(r.get_ref().task_queue.clone());
898            r.extensions_mut().insert(labels);
899        }
900    );
901    (
902        create_schedule,
903        CreateScheduleRequest,
904        CreateScheduleResponse,
905        |r| {
906            let labels = namespaced_request!(r);
907            r.extensions_mut().insert(labels);
908        }
909    );
910    (
911        describe_schedule,
912        DescribeScheduleRequest,
913        DescribeScheduleResponse,
914        |r| {
915            let labels = namespaced_request!(r);
916            r.extensions_mut().insert(labels);
917        }
918    );
919    (
920        update_schedule,
921        UpdateScheduleRequest,
922        UpdateScheduleResponse,
923        |r| {
924            let labels = namespaced_request!(r);
925            r.extensions_mut().insert(labels);
926        }
927    );
928    (
929        patch_schedule,
930        PatchScheduleRequest,
931        PatchScheduleResponse,
932        |r| {
933            let labels = namespaced_request!(r);
934            r.extensions_mut().insert(labels);
935        }
936    );
937    (
938        list_schedule_matching_times,
939        ListScheduleMatchingTimesRequest,
940        ListScheduleMatchingTimesResponse,
941        |r| {
942            let labels = namespaced_request!(r);
943            r.extensions_mut().insert(labels);
944        }
945    );
946    (
947        delete_schedule,
948        DeleteScheduleRequest,
949        DeleteScheduleResponse,
950        |r| {
951            let labels = namespaced_request!(r);
952            r.extensions_mut().insert(labels);
953        }
954    );
955    (
956        list_schedules,
957        ListSchedulesRequest,
958        ListSchedulesResponse,
959        |r| {
960            let labels = namespaced_request!(r);
961            r.extensions_mut().insert(labels);
962        }
963    );
964    (
965        update_worker_build_id_compatibility,
966        UpdateWorkerBuildIdCompatibilityRequest,
967        UpdateWorkerBuildIdCompatibilityResponse,
968        |r| {
969            let mut labels = namespaced_request!(r);
970            labels.task_q_str(r.get_ref().task_queue.clone());
971            r.extensions_mut().insert(labels);
972        }
973    );
974    (
975        get_worker_build_id_compatibility,
976        GetWorkerBuildIdCompatibilityRequest,
977        GetWorkerBuildIdCompatibilityResponse,
978        |r| {
979            let mut labels = namespaced_request!(r);
980            labels.task_q_str(r.get_ref().task_queue.clone());
981            r.extensions_mut().insert(labels);
982        }
983    );
984    (
985        get_worker_task_reachability,
986        GetWorkerTaskReachabilityRequest,
987        GetWorkerTaskReachabilityResponse,
988        |r| {
989            let labels = namespaced_request!(r);
990            r.extensions_mut().insert(labels);
991        }
992    );
993    (
994        update_workflow_execution,
995        UpdateWorkflowExecutionRequest,
996        UpdateWorkflowExecutionResponse,
997        |r| {
998            let labels = namespaced_request!(r);
999            let exts = r.extensions_mut();
1000            exts.insert(labels);
1001            exts.insert(IsUserLongPoll);
1002        }
1003    );
1004    (
1005        poll_workflow_execution_update,
1006        PollWorkflowExecutionUpdateRequest,
1007        PollWorkflowExecutionUpdateResponse,
1008        |r| {
1009            let labels = namespaced_request!(r);
1010            r.extensions_mut().insert(labels);
1011        }
1012    );
1013    (
1014        start_batch_operation,
1015        StartBatchOperationRequest,
1016        StartBatchOperationResponse,
1017        |r| {
1018            let labels = namespaced_request!(r);
1019            r.extensions_mut().insert(labels);
1020        }
1021    );
1022    (
1023        stop_batch_operation,
1024        StopBatchOperationRequest,
1025        StopBatchOperationResponse,
1026        |r| {
1027            let labels = namespaced_request!(r);
1028            r.extensions_mut().insert(labels);
1029        }
1030    );
1031    (
1032        describe_batch_operation,
1033        DescribeBatchOperationRequest,
1034        DescribeBatchOperationResponse,
1035        |r| {
1036            let labels = namespaced_request!(r);
1037            r.extensions_mut().insert(labels);
1038        }
1039    );
1040    (
1041        describe_deployment,
1042        DescribeDeploymentRequest,
1043        DescribeDeploymentResponse,
1044        |r| {
1045            let labels = namespaced_request!(r);
1046            r.extensions_mut().insert(labels);
1047        }
1048    );
1049    (
1050        list_batch_operations,
1051        ListBatchOperationsRequest,
1052        ListBatchOperationsResponse,
1053        |r| {
1054            let labels = namespaced_request!(r);
1055            r.extensions_mut().insert(labels);
1056        }
1057    );
1058    (
1059        list_deployments,
1060        ListDeploymentsRequest,
1061        ListDeploymentsResponse,
1062        |r| {
1063            let labels = namespaced_request!(r);
1064            r.extensions_mut().insert(labels);
1065        }
1066    );
1067    (
1068        execute_multi_operation,
1069        ExecuteMultiOperationRequest,
1070        ExecuteMultiOperationResponse,
1071        |r| {
1072            let labels = namespaced_request!(r);
1073            r.extensions_mut().insert(labels);
1074        }
1075    );
1076    (
1077        get_current_deployment,
1078        GetCurrentDeploymentRequest,
1079        GetCurrentDeploymentResponse,
1080        |r| {
1081            let labels = namespaced_request!(r);
1082            r.extensions_mut().insert(labels);
1083        }
1084    );
1085    (
1086        get_deployment_reachability,
1087        GetDeploymentReachabilityRequest,
1088        GetDeploymentReachabilityResponse,
1089        |r| {
1090            let labels = namespaced_request!(r);
1091            r.extensions_mut().insert(labels);
1092        }
1093    );
1094    (
1095        get_worker_versioning_rules,
1096        GetWorkerVersioningRulesRequest,
1097        GetWorkerVersioningRulesResponse,
1098        |r| {
1099            let mut labels = namespaced_request!(r);
1100            labels.task_q_str(&r.get_ref().task_queue);
1101            r.extensions_mut().insert(labels);
1102        }
1103    );
1104    (
1105        update_worker_versioning_rules,
1106        UpdateWorkerVersioningRulesRequest,
1107        UpdateWorkerVersioningRulesResponse,
1108        |r| {
1109            let mut labels = namespaced_request!(r);
1110            labels.task_q_str(&r.get_ref().task_queue);
1111            r.extensions_mut().insert(labels);
1112        }
1113    );
1114    (
1115        poll_nexus_task_queue,
1116        PollNexusTaskQueueRequest,
1117        PollNexusTaskQueueResponse,
1118        |r| {
1119            let mut labels = namespaced_request!(r);
1120            labels.task_q(r.get_ref().task_queue.clone());
1121            r.extensions_mut().insert(labels);
1122        }
1123    );
1124    (
1125        respond_nexus_task_completed,
1126        RespondNexusTaskCompletedRequest,
1127        RespondNexusTaskCompletedResponse,
1128        |r| {
1129            let labels = namespaced_request!(r);
1130            r.extensions_mut().insert(labels);
1131        }
1132    );
1133    (
1134        respond_nexus_task_failed,
1135        RespondNexusTaskFailedRequest,
1136        RespondNexusTaskFailedResponse,
1137        |r| {
1138            let labels = namespaced_request!(r);
1139            r.extensions_mut().insert(labels);
1140        }
1141    );
1142    (
1143        set_current_deployment,
1144        SetCurrentDeploymentRequest,
1145        SetCurrentDeploymentResponse,
1146        |r| {
1147            let labels = namespaced_request!(r);
1148            r.extensions_mut().insert(labels);
1149        }
1150    );
1151    (
1152        shutdown_worker,
1153        ShutdownWorkerRequest,
1154        ShutdownWorkerResponse,
1155        |r| {
1156            let labels = namespaced_request!(r);
1157            r.extensions_mut().insert(labels);
1158        }
1159    );
1160    (
1161        update_activity_options,
1162        UpdateActivityOptionsRequest,
1163        UpdateActivityOptionsResponse,
1164        |r| {
1165            let labels = namespaced_request!(r);
1166            r.extensions_mut().insert(labels);
1167        }
1168    );
1169    (
1170        pause_activity,
1171        PauseActivityRequest,
1172        PauseActivityResponse,
1173        |r| {
1174            let labels = namespaced_request!(r);
1175            r.extensions_mut().insert(labels);
1176        }
1177    );
1178    (
1179        unpause_activity,
1180        UnpauseActivityRequest,
1181        UnpauseActivityResponse,
1182        |r| {
1183            let labels = namespaced_request!(r);
1184            r.extensions_mut().insert(labels);
1185        }
1186    );
1187    (
1188        update_workflow_execution_options,
1189        UpdateWorkflowExecutionOptionsRequest,
1190        UpdateWorkflowExecutionOptionsResponse,
1191        |r| {
1192            let labels = namespaced_request!(r);
1193            r.extensions_mut().insert(labels);
1194        }
1195    );
1196    (
1197        reset_activity,
1198        ResetActivityRequest,
1199        ResetActivityResponse,
1200        |r| {
1201            let labels = namespaced_request!(r);
1202            r.extensions_mut().insert(labels);
1203        }
1204    );
1205    (
1206        delete_worker_deployment,
1207        DeleteWorkerDeploymentRequest,
1208        DeleteWorkerDeploymentResponse,
1209        |r| {
1210            let labels = namespaced_request!(r);
1211            r.extensions_mut().insert(labels);
1212        }
1213    );
1214    (
1215        delete_worker_deployment_version,
1216        DeleteWorkerDeploymentVersionRequest,
1217        DeleteWorkerDeploymentVersionResponse,
1218        |r| {
1219            let labels = namespaced_request!(r);
1220            r.extensions_mut().insert(labels);
1221        }
1222    );
1223    (
1224        describe_worker_deployment,
1225        DescribeWorkerDeploymentRequest,
1226        DescribeWorkerDeploymentResponse,
1227        |r| {
1228            let labels = namespaced_request!(r);
1229            r.extensions_mut().insert(labels);
1230        }
1231    );
1232    (
1233        describe_worker_deployment_version,
1234        DescribeWorkerDeploymentVersionRequest,
1235        DescribeWorkerDeploymentVersionResponse,
1236        |r| {
1237            let labels = namespaced_request!(r);
1238            r.extensions_mut().insert(labels);
1239        }
1240    );
1241    (
1242        list_worker_deployments,
1243        ListWorkerDeploymentsRequest,
1244        ListWorkerDeploymentsResponse,
1245        |r| {
1246            let labels = namespaced_request!(r);
1247            r.extensions_mut().insert(labels);
1248        }
1249    );
1250    (
1251        set_worker_deployment_current_version,
1252        SetWorkerDeploymentCurrentVersionRequest,
1253        SetWorkerDeploymentCurrentVersionResponse,
1254        |r| {
1255            let labels = namespaced_request!(r);
1256            r.extensions_mut().insert(labels);
1257        }
1258    );
1259    (
1260        set_worker_deployment_ramping_version,
1261        SetWorkerDeploymentRampingVersionRequest,
1262        SetWorkerDeploymentRampingVersionResponse,
1263        |r| {
1264            let labels = namespaced_request!(r);
1265            r.extensions_mut().insert(labels);
1266        }
1267    );
1268    (
1269        update_worker_deployment_version_metadata,
1270        UpdateWorkerDeploymentVersionMetadataRequest,
1271        UpdateWorkerDeploymentVersionMetadataResponse,
1272        |r| {
1273            let labels = namespaced_request!(r);
1274            r.extensions_mut().insert(labels);
1275        }
1276    );
1277    (
1278        list_workers,
1279        ListWorkersRequest,
1280        ListWorkersResponse,
1281        |r| {
1282            let labels = namespaced_request!(r);
1283            r.extensions_mut().insert(labels);
1284        }
1285    );
1286    (
1287        record_worker_heartbeat,
1288        RecordWorkerHeartbeatRequest,
1289        RecordWorkerHeartbeatResponse,
1290        |r| {
1291            let labels = namespaced_request!(r);
1292            r.extensions_mut().insert(labels);
1293        }
1294    );
1295    (
1296        update_task_queue_config,
1297        UpdateTaskQueueConfigRequest,
1298        UpdateTaskQueueConfigResponse,
1299        |r| {
1300            let mut labels = namespaced_request!(r);
1301            labels.task_q_str(r.get_ref().task_queue.clone());
1302            r.extensions_mut().insert(labels);
1303        }
1304    );
1305    (
1306        fetch_worker_config,
1307        FetchWorkerConfigRequest,
1308        FetchWorkerConfigResponse,
1309        |r| {
1310            let labels = namespaced_request!(r);
1311            r.extensions_mut().insert(labels);
1312        }
1313    );
1314    (
1315        update_worker_config,
1316        UpdateWorkerConfigRequest,
1317        UpdateWorkerConfigResponse,
1318        |r| {
1319            let labels = namespaced_request!(r);
1320            r.extensions_mut().insert(labels);
1321        }
1322    );
1323}
1324
1325proxier! {
1326    OperatorService; ALL_IMPLEMENTED_OPERATOR_SERVICE_RPCS; OperatorServiceClient; operator_client_mut;
1327    (add_search_attributes, AddSearchAttributesRequest, AddSearchAttributesResponse);
1328    (remove_search_attributes, RemoveSearchAttributesRequest, RemoveSearchAttributesResponse);
1329    (list_search_attributes, ListSearchAttributesRequest, ListSearchAttributesResponse);
1330    (delete_namespace, DeleteNamespaceRequest, DeleteNamespaceResponse,
1331        |r| {
1332            let labels = namespaced_request!(r);
1333            r.extensions_mut().insert(labels);
1334        }
1335    );
1336    (add_or_update_remote_cluster, AddOrUpdateRemoteClusterRequest, AddOrUpdateRemoteClusterResponse);
1337    (remove_remote_cluster, RemoveRemoteClusterRequest, RemoveRemoteClusterResponse);
1338    (list_clusters, ListClustersRequest, ListClustersResponse);
1339    (get_nexus_endpoint, GetNexusEndpointRequest, GetNexusEndpointResponse);
1340    (create_nexus_endpoint, CreateNexusEndpointRequest, CreateNexusEndpointResponse);
1341    (update_nexus_endpoint, UpdateNexusEndpointRequest, UpdateNexusEndpointResponse);
1342    (delete_nexus_endpoint, DeleteNexusEndpointRequest, DeleteNexusEndpointResponse);
1343    (list_nexus_endpoints, ListNexusEndpointsRequest, ListNexusEndpointsResponse);
1344}
1345
1346proxier! {
1347    CloudService; ALL_IMPLEMENTED_CLOUD_SERVICE_RPCS; CloudServiceClient; cloud_client_mut;
1348    (get_users, cloudreq::GetUsersRequest, cloudreq::GetUsersResponse);
1349    (get_user, cloudreq::GetUserRequest, cloudreq::GetUserResponse);
1350    (create_user, cloudreq::CreateUserRequest, cloudreq::CreateUserResponse);
1351    (update_user, cloudreq::UpdateUserRequest, cloudreq::UpdateUserResponse);
1352    (delete_user, cloudreq::DeleteUserRequest, cloudreq::DeleteUserResponse);
1353    (set_user_namespace_access, cloudreq::SetUserNamespaceAccessRequest, cloudreq::SetUserNamespaceAccessResponse);
1354    (get_async_operation, cloudreq::GetAsyncOperationRequest, cloudreq::GetAsyncOperationResponse);
1355    (create_namespace, cloudreq::CreateNamespaceRequest, cloudreq::CreateNamespaceResponse);
1356    (get_namespaces, cloudreq::GetNamespacesRequest, cloudreq::GetNamespacesResponse);
1357    (get_namespace, cloudreq::GetNamespaceRequest, cloudreq::GetNamespaceResponse,
1358        |r| {
1359            let labels = namespaced_request!(r);
1360            r.extensions_mut().insert(labels);
1361        }
1362    );
1363    (update_namespace, cloudreq::UpdateNamespaceRequest, cloudreq::UpdateNamespaceResponse,
1364        |r| {
1365            let labels = namespaced_request!(r);
1366            r.extensions_mut().insert(labels);
1367        }
1368    );
1369    (rename_custom_search_attribute, cloudreq::RenameCustomSearchAttributeRequest, cloudreq::RenameCustomSearchAttributeResponse);
1370    (delete_namespace, cloudreq::DeleteNamespaceRequest, cloudreq::DeleteNamespaceResponse,
1371        |r| {
1372            let labels = namespaced_request!(r);
1373            r.extensions_mut().insert(labels);
1374        }
1375    );
1376    (failover_namespace_region, cloudreq::FailoverNamespaceRegionRequest, cloudreq::FailoverNamespaceRegionResponse);
1377    (add_namespace_region, cloudreq::AddNamespaceRegionRequest, cloudreq::AddNamespaceRegionResponse);
1378    (delete_namespace_region, cloudreq::DeleteNamespaceRegionRequest, cloudreq::DeleteNamespaceRegionResponse);
1379    (get_regions, cloudreq::GetRegionsRequest, cloudreq::GetRegionsResponse);
1380    (get_region, cloudreq::GetRegionRequest, cloudreq::GetRegionResponse);
1381    (get_api_keys, cloudreq::GetApiKeysRequest, cloudreq::GetApiKeysResponse);
1382    (get_api_key, cloudreq::GetApiKeyRequest, cloudreq::GetApiKeyResponse);
1383    (create_api_key, cloudreq::CreateApiKeyRequest, cloudreq::CreateApiKeyResponse);
1384    (update_api_key, cloudreq::UpdateApiKeyRequest, cloudreq::UpdateApiKeyResponse);
1385    (delete_api_key, cloudreq::DeleteApiKeyRequest, cloudreq::DeleteApiKeyResponse);
1386    (get_nexus_endpoints, cloudreq::GetNexusEndpointsRequest, cloudreq::GetNexusEndpointsResponse);
1387    (get_nexus_endpoint, cloudreq::GetNexusEndpointRequest, cloudreq::GetNexusEndpointResponse);
1388    (create_nexus_endpoint, cloudreq::CreateNexusEndpointRequest, cloudreq::CreateNexusEndpointResponse);
1389    (update_nexus_endpoint, cloudreq::UpdateNexusEndpointRequest, cloudreq::UpdateNexusEndpointResponse);
1390    (delete_nexus_endpoint, cloudreq::DeleteNexusEndpointRequest, cloudreq::DeleteNexusEndpointResponse);
1391    (get_user_groups, cloudreq::GetUserGroupsRequest, cloudreq::GetUserGroupsResponse);
1392    (get_user_group, cloudreq::GetUserGroupRequest, cloudreq::GetUserGroupResponse);
1393    (create_user_group, cloudreq::CreateUserGroupRequest, cloudreq::CreateUserGroupResponse);
1394    (update_user_group, cloudreq::UpdateUserGroupRequest, cloudreq::UpdateUserGroupResponse);
1395    (delete_user_group, cloudreq::DeleteUserGroupRequest, cloudreq::DeleteUserGroupResponse);
1396    (add_user_group_member, cloudreq::AddUserGroupMemberRequest, cloudreq::AddUserGroupMemberResponse);
1397    (remove_user_group_member, cloudreq::RemoveUserGroupMemberRequest, cloudreq::RemoveUserGroupMemberResponse);
1398    (get_user_group_members, cloudreq::GetUserGroupMembersRequest, cloudreq::GetUserGroupMembersResponse);
1399    (set_user_group_namespace_access, cloudreq::SetUserGroupNamespaceAccessRequest, cloudreq::SetUserGroupNamespaceAccessResponse);
1400    (create_service_account, cloudreq::CreateServiceAccountRequest, cloudreq::CreateServiceAccountResponse);
1401    (get_service_account, cloudreq::GetServiceAccountRequest, cloudreq::GetServiceAccountResponse);
1402    (get_service_accounts, cloudreq::GetServiceAccountsRequest, cloudreq::GetServiceAccountsResponse);
1403    (update_service_account, cloudreq::UpdateServiceAccountRequest, cloudreq::UpdateServiceAccountResponse);
1404    (delete_service_account, cloudreq::DeleteServiceAccountRequest, cloudreq::DeleteServiceAccountResponse);
1405    (get_usage, cloudreq::GetUsageRequest, cloudreq::GetUsageResponse);
1406    (get_account, cloudreq::GetAccountRequest, cloudreq::GetAccountResponse);
1407    (update_account, cloudreq::UpdateAccountRequest, cloudreq::UpdateAccountResponse);
1408    (create_namespace_export_sink, cloudreq::CreateNamespaceExportSinkRequest, cloudreq::CreateNamespaceExportSinkResponse);
1409    (get_namespace_export_sink, cloudreq::GetNamespaceExportSinkRequest, cloudreq::GetNamespaceExportSinkResponse);
1410    (get_namespace_export_sinks, cloudreq::GetNamespaceExportSinksRequest, cloudreq::GetNamespaceExportSinksResponse);
1411    (update_namespace_export_sink, cloudreq::UpdateNamespaceExportSinkRequest, cloudreq::UpdateNamespaceExportSinkResponse);
1412    (delete_namespace_export_sink, cloudreq::DeleteNamespaceExportSinkRequest, cloudreq::DeleteNamespaceExportSinkResponse);
1413    (validate_namespace_export_sink, cloudreq::ValidateNamespaceExportSinkRequest, cloudreq::ValidateNamespaceExportSinkResponse);
1414    (update_namespace_tags, cloudreq::UpdateNamespaceTagsRequest, cloudreq::UpdateNamespaceTagsResponse);
1415    (create_connectivity_rule, cloudreq::CreateConnectivityRuleRequest, cloudreq::CreateConnectivityRuleResponse);
1416    (get_connectivity_rule, cloudreq::GetConnectivityRuleRequest, cloudreq::GetConnectivityRuleResponse);
1417    (get_connectivity_rules, cloudreq::GetConnectivityRulesRequest, cloudreq::GetConnectivityRulesResponse);
1418    (delete_connectivity_rule, cloudreq::DeleteConnectivityRuleRequest, cloudreq::DeleteConnectivityRuleResponse);
1419}
1420
1421proxier! {
1422    TestService; ALL_IMPLEMENTED_TEST_SERVICE_RPCS; TestServiceClient; test_client_mut;
1423    (lock_time_skipping, LockTimeSkippingRequest, LockTimeSkippingResponse);
1424    (unlock_time_skipping, UnlockTimeSkippingRequest, UnlockTimeSkippingResponse);
1425    (sleep, SleepRequest, SleepResponse);
1426    (sleep_until, SleepUntilRequest, SleepResponse);
1427    (unlock_time_skipping_with_sleep, SleepRequest, SleepResponse);
1428    (get_current_time, (), GetCurrentTimeResponse);
1429}
1430
1431proxier! {
1432    HealthService; ALL_IMPLEMENTED_HEALTH_SERVICE_RPCS; HealthClient; health_client_mut;
1433    (check, HealthCheckRequest, HealthCheckResponse);
1434    (watch, HealthCheckRequest, tonic::codec::Streaming<HealthCheckResponse>);
1435}
1436
1437#[cfg(test)]
1438mod tests {
1439    use super::*;
1440    use crate::{ClientOptionsBuilder, RetryClient};
1441    use std::collections::HashSet;
1442    use temporal_sdk_core_protos::temporal::api::{
1443        operatorservice::v1::DeleteNamespaceRequest, workflowservice::v1::ListNamespacesRequest,
1444    };
1445
1446    // Just to help make sure some stuff compiles. Not run.
1447    #[allow(dead_code)]
1448    async fn raw_client_retry_compiles() {
1449        let opts = ClientOptionsBuilder::default().build().unwrap();
1450        let raw_client = opts.connect_no_namespace(None).await.unwrap();
1451        let mut retry_client = RetryClient::new(raw_client, opts.retry_config);
1452
1453        let list_ns_req = ListNamespacesRequest::default();
1454        let fact = |c: &mut RetryClient<_>, req| {
1455            let mut c = c.workflow_client_mut().clone();
1456            async move { c.list_namespaces(req).await }.boxed()
1457        };
1458        retry_client
1459            .call("whatever", fact, Request::new(list_ns_req.clone()))
1460            .await
1461            .unwrap();
1462
1463        // Operator svc method
1464        let op_del_ns_req = DeleteNamespaceRequest::default();
1465        let fact = |c: &mut RetryClient<_>, req| {
1466            let mut c = c.operator_client_mut().clone();
1467            async move { c.delete_namespace(req).await }.boxed()
1468        };
1469        retry_client
1470            .call("whatever", fact, Request::new(op_del_ns_req.clone()))
1471            .await
1472            .unwrap();
1473
1474        // Cloud svc method
1475        let cloud_del_ns_req = cloudreq::DeleteNamespaceRequest::default();
1476        let fact = |c: &mut RetryClient<_>, req| {
1477            let mut c = c.cloud_client_mut().clone();
1478            async move { c.delete_namespace(req).await }.boxed()
1479        };
1480        retry_client
1481            .call("whatever", fact, Request::new(cloud_del_ns_req.clone()))
1482            .await
1483            .unwrap();
1484
1485        // Verify calling through traits works
1486        retry_client.list_namespaces(list_ns_req).await.unwrap();
1487        // Have to disambiguate operator and cloud service
1488        OperatorService::delete_namespace(&mut retry_client, op_del_ns_req)
1489            .await
1490            .unwrap();
1491        CloudService::delete_namespace(&mut retry_client, cloud_del_ns_req)
1492            .await
1493            .unwrap();
1494        retry_client.get_current_time(()).await.unwrap();
1495        retry_client
1496            .check(HealthCheckRequest::default())
1497            .await
1498            .unwrap();
1499    }
1500
1501    fn verify_methods(proto_def_str: &str, impl_list: &[&str]) {
1502        let methods: Vec<_> = proto_def_str
1503            .lines()
1504            .map(|l| l.trim())
1505            .filter(|l| l.starts_with("rpc"))
1506            .map(|l| {
1507                let stripped = l.strip_prefix("rpc ").unwrap();
1508                stripped[..stripped.find('(').unwrap()].trim()
1509            })
1510            .collect();
1511        let no_underscores: HashSet<_> = impl_list.iter().map(|x| x.replace('_', "")).collect();
1512        let mut not_implemented = vec![];
1513        for method in methods {
1514            if !no_underscores.contains(&method.to_lowercase()) {
1515                not_implemented.push(method);
1516            }
1517        }
1518        if !not_implemented.is_empty() {
1519            panic!(
1520                "The following RPC methods are not implemented by raw client: {not_implemented:?}"
1521            );
1522        }
1523    }
1524    #[test]
1525    fn verify_all_workflow_service_methods_implemented() {
1526        // This is less work than trying to hook into the codegen process
1527        let proto_def = include_str!(
1528            "../../sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto"
1529        );
1530        verify_methods(proto_def, ALL_IMPLEMENTED_WORKFLOW_SERVICE_RPCS);
1531    }
1532
1533    #[test]
1534    fn verify_all_operator_service_methods_implemented() {
1535        let proto_def = include_str!(
1536            "../../sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/service.proto"
1537        );
1538        verify_methods(proto_def, ALL_IMPLEMENTED_OPERATOR_SERVICE_RPCS);
1539    }
1540
1541    #[test]
1542    fn verify_all_cloud_service_methods_implemented() {
1543        let proto_def = include_str!(
1544            "../../sdk-core-protos/protos/api_cloud_upstream/temporal/api/cloud/cloudservice/v1/service.proto"
1545        );
1546        verify_methods(proto_def, ALL_IMPLEMENTED_CLOUD_SERVICE_RPCS);
1547    }
1548
1549    #[test]
1550    fn verify_all_test_service_methods_implemented() {
1551        let proto_def = include_str!(
1552            "../../sdk-core-protos/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto"
1553        );
1554        verify_methods(proto_def, ALL_IMPLEMENTED_TEST_SERVICE_RPCS);
1555    }
1556
1557    #[test]
1558    fn verify_all_health_service_methods_implemented() {
1559        let proto_def = include_str!("../../sdk-core-protos/protos/grpc/health/v1/health.proto");
1560        verify_methods(proto_def, ALL_IMPLEMENTED_HEALTH_SERVICE_RPCS);
1561    }
1562}