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