Skip to main content

d_engine_proto/generated/
d_engine.client.rs

1// This file is @generated by prost-build.
2/// Write operation-specific command
3#[derive(serde::Serialize, serde::Deserialize)]
4#[derive(Clone, PartialEq, ::prost::Message)]
5pub struct WriteCommand {
6    #[prost(oneof = "write_command::Operation", tags = "1, 2, 3")]
7    pub operation: ::core::option::Option<write_command::Operation>,
8}
9/// Nested message and enum types in `WriteCommand`.
10pub mod write_command {
11    #[derive(serde::Serialize, serde::Deserialize)]
12    #[derive(Clone, PartialEq, ::prost::Message)]
13    pub struct Insert {
14        #[prost(bytes = "bytes", tag = "1")]
15        pub key: ::prost::bytes::Bytes,
16        #[prost(bytes = "bytes", tag = "2")]
17        pub value: ::prost::bytes::Bytes,
18        /// Time-to-live in seconds. 0 means no expiration (default).
19        /// Non-zero values specify expiration time in seconds from insertion.
20        #[prost(uint64, tag = "3")]
21        pub ttl_secs: u64,
22    }
23    #[derive(serde::Serialize, serde::Deserialize)]
24    #[derive(Clone, PartialEq, ::prost::Message)]
25    pub struct Delete {
26        #[prost(bytes = "bytes", tag = "1")]
27        pub key: ::prost::bytes::Bytes,
28    }
29    #[derive(serde::Serialize, serde::Deserialize)]
30    #[derive(Clone, PartialEq, ::prost::Message)]
31    pub struct CompareAndSwap {
32        #[prost(bytes = "bytes", tag = "1")]
33        pub key: ::prost::bytes::Bytes,
34        /// None means key must not exist
35        #[prost(bytes = "bytes", optional, tag = "2")]
36        pub expected_value: ::core::option::Option<::prost::bytes::Bytes>,
37        /// New value to set if comparison succeeds
38        #[prost(bytes = "bytes", tag = "3")]
39        pub new_value: ::prost::bytes::Bytes,
40    }
41    #[derive(serde::Serialize, serde::Deserialize)]
42    #[derive(Clone, PartialEq, ::prost::Oneof)]
43    pub enum Operation {
44        #[prost(message, tag = "1")]
45        Insert(Insert),
46        #[prost(message, tag = "2")]
47        Delete(Delete),
48        #[prost(message, tag = "3")]
49        CompareAndSwap(CompareAndSwap),
50    }
51}
52#[derive(serde::Serialize, serde::Deserialize)]
53#[derive(Clone, PartialEq, ::prost::Message)]
54pub struct ClientWriteRequest {
55    #[prost(uint32, tag = "1")]
56    pub client_id: u32,
57    /// Changed from 'repeated commands' to singular 'command' (1 request = 1 command)
58    #[prost(message, optional, tag = "2")]
59    pub command: ::core::option::Option<WriteCommand>,
60}
61#[derive(serde::Serialize, serde::Deserialize)]
62#[derive(Clone, PartialEq, ::prost::Message)]
63pub struct ClientReadRequest {
64    #[prost(uint32, tag = "1")]
65    pub client_id: u32,
66    /// Key list to be read
67    #[prost(bytes = "bytes", repeated, tag = "2")]
68    pub keys: ::prost::alloc::vec::Vec<::prost::bytes::Bytes>,
69    /// Optional consistency policy for this request
70    ///
71    /// When present: Client explicitly specifies consistency requirements
72    /// When absent: Use cluster's configured default policy
73    #[prost(enumeration = "ReadConsistencyPolicy", optional, tag = "3")]
74    pub consistency_policy: ::core::option::Option<i32>,
75}
76/// Write operation result
77#[derive(serde::Serialize, serde::Deserialize)]
78#[derive(Clone, Copy, PartialEq, ::prost::Message)]
79pub struct WriteResult {
80    /// Future: uint64 version = 2;
81    /// Future: bytes prev_value = 3;
82    #[prost(bool, tag = "1")]
83    pub succeeded: bool,
84}
85#[derive(serde::Serialize, serde::Deserialize)]
86#[derive(Clone, PartialEq, ::prost::Message)]
87pub struct ClientResponse {
88    #[prost(enumeration = "super::error::ErrorCode", tag = "1")]
89    pub error: i32,
90    #[prost(message, optional, tag = "4")]
91    pub metadata: ::core::option::Option<super::error::ErrorMetadata>,
92    #[prost(oneof = "client_response::SuccessResult", tags = "2, 3")]
93    pub success_result: ::core::option::Option<client_response::SuccessResult>,
94}
95/// Nested message and enum types in `ClientResponse`.
96pub mod client_response {
97    #[derive(serde::Serialize, serde::Deserialize)]
98    #[derive(Clone, PartialEq, ::prost::Oneof)]
99    pub enum SuccessResult {
100        #[prost(message, tag = "2")]
101        WriteResult(super::WriteResult),
102        #[prost(message, tag = "3")]
103        ReadData(super::ReadResults),
104    }
105}
106/// Renamed from ClientGetResult
107#[derive(serde::Serialize, serde::Deserialize)]
108#[derive(Clone, PartialEq, ::prost::Message)]
109pub struct ClientResult {
110    #[prost(bytes = "bytes", tag = "1")]
111    pub key: ::prost::bytes::Bytes,
112    #[prost(bytes = "bytes", tag = "2")]
113    pub value: ::prost::bytes::Bytes,
114}
115#[derive(serde::Serialize, serde::Deserialize)]
116#[derive(Clone, PartialEq, ::prost::Message)]
117pub struct ReadResults {
118    #[prost(message, repeated, tag = "1")]
119    pub results: ::prost::alloc::vec::Vec<ClientResult>,
120}
121/// A single key-value pair returned by a prefix scan.
122#[derive(serde::Serialize, serde::Deserialize)]
123#[derive(Clone, PartialEq, ::prost::Message)]
124pub struct KvEntry {
125    #[prost(bytes = "bytes", tag = "1")]
126    pub key: ::prost::bytes::Bytes,
127    #[prost(bytes = "bytes", tag = "2")]
128    pub value: ::prost::bytes::Bytes,
129}
130/// Request to scan all keys under a namespace prefix.
131/// Scan is served from the leader's state machine at last_applied.
132/// consistency_policy is not supported; tracked in #381.
133#[derive(serde::Serialize, serde::Deserialize)]
134#[derive(Clone, PartialEq, ::prost::Message)]
135pub struct ScanRequest {
136    #[prost(uint32, tag = "1")]
137    pub client_id: u32,
138    /// Prefix to scan. Must start with '/'. e.g. b"/services/".
139    #[prost(bytes = "bytes", tag = "2")]
140    pub prefix: ::prost::bytes::Bytes,
141}
142/// Response from a prefix scan.
143#[derive(serde::Serialize, serde::Deserialize)]
144#[derive(Clone, PartialEq, ::prost::Message)]
145pub struct ScanResponse {
146    /// All (key, value) pairs whose key starts with the requested prefix.
147    #[prost(message, repeated, tag = "1")]
148    pub entries: ::prost::alloc::vec::Vec<KvEntry>,
149    /// Raft applied index at the moment of the scan.
150    /// Use as the watch-event filter anchor: skip events where event.revision <= revision.
151    #[prost(uint64, tag = "2")]
152    pub revision: u64,
153}
154/// Request to start a server-side membership watch stream.
155#[derive(serde::Serialize, serde::Deserialize)]
156#[derive(Clone, Copy, PartialEq, ::prost::Message)]
157pub struct WatchMembershipRequest {
158    #[prost(uint32, tag = "1")]
159    pub client_id: u32,
160}
161/// Point-in-time snapshot of committed cluster membership.
162///
163/// Delivered on every committed ConfChange entry.
164/// `committed_index` is strictly monotonically increasing and serves as an
165/// idempotency key for schedulers.
166#[derive(serde::Serialize, serde::Deserialize)]
167#[derive(Clone, PartialEq, ::prost::Message)]
168pub struct MembershipSnapshot {
169    /// Current voting members (Follower / Leader role).
170    #[prost(uint32, repeated, tag = "1")]
171    pub members: ::prost::alloc::vec::Vec<u32>,
172    /// Current non-voting learners.
173    #[prost(uint32, repeated, tag = "2")]
174    pub learners: ::prost::alloc::vec::Vec<u32>,
175    /// Raft log index of the ConfChange entry that produced this snapshot.
176    #[prost(uint64, tag = "3")]
177    pub committed_index: u64,
178}
179/// Request to watch for changes on a key or key prefix.
180#[derive(serde::Serialize, serde::Deserialize)]
181#[derive(Clone, PartialEq, ::prost::Message)]
182pub struct WatchRequest {
183    #[prost(uint32, tag = "1")]
184    pub client_id: u32,
185    /// Key to watch.
186    /// prefix=false: exact key match.
187    /// prefix=true:  prefix match — key must start with "/" and end with "/".
188    ///                e.g. "/config/" watches all keys under /config/.
189    #[prost(bytes = "bytes", tag = "2")]
190    pub key: ::prost::bytes::Bytes,
191    /// When true, key is treated as a path prefix (must end with "/").
192    /// Default false preserves backwards-compatible exact-match behaviour.
193    #[prost(bool, tag = "3")]
194    pub prefix: bool,
195    /// When true, each WatchResponse includes the value that existed before
196    /// the mutation (prev_value). Default false; server skips the extra read
197    /// when no watcher requests it.
198    #[prost(bool, tag = "4")]
199    pub prev_kv: bool,
200}
201/// Response containing a watch event notification
202#[derive(serde::Serialize, serde::Deserialize)]
203#[derive(Clone, PartialEq, ::prost::Message)]
204pub struct WatchResponse {
205    /// The key that changed
206    #[prost(bytes = "bytes", tag = "1")]
207    pub key: ::prost::bytes::Bytes,
208    /// The new value (empty for DELETE events)
209    #[prost(bytes = "bytes", tag = "2")]
210    pub value: ::prost::bytes::Bytes,
211    /// Type of change that occurred
212    #[prost(enumeration = "WatchEventType", tag = "3")]
213    pub event_type: i32,
214    /// Error information if watch failed
215    #[prost(enumeration = "super::error::ErrorCode", tag = "4")]
216    pub error: i32,
217    /// Raft applied index at the time this event was produced.
218    /// Monotonically increasing. Clients use this as an anchor after receiving
219    /// CANCELED: re-read state, then re-register watching from revision+1.
220    #[prost(uint64, tag = "5")]
221    pub revision: u64,
222    /// Value before this mutation. Empty when:
223    ///    - key did not exist before the write
224    ///    - event_type is PROGRESS or CANCELED
225    ///    - watcher was registered with prev_kv = false
226    #[prost(bytes = "bytes", tag = "6")]
227    pub prev_value: ::prost::bytes::Bytes,
228}
229/// Read consistency policy for controlling read operation guarantees
230///
231/// Allows clients to choose between performance and consistency trade-offs
232/// on a per-request basis when supported by the cluster configuration.
233#[derive(serde::Serialize, serde::Deserialize)]
234#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
235#[repr(i32)]
236pub enum ReadConsistencyPolicy {
237    /// Lease-based reads for better performance with weaker consistency
238    ///
239    /// Leader serves reads locally without contacting followers during lease period.
240    /// Provides lower latency but slightly weaker consistency guarantees.
241    LeaseRead = 0,
242    /// Fully linearizable reads for strongest consistency
243    ///
244    /// Leader verifies its leadership with a quorum before serving the read,
245    /// ensuring strict linearizability. Guarantees that all reads reflect
246    /// the most recent committed value in the cluster.
247    LinearizableRead = 1,
248    /// Eventually consistent reads from any node
249    ///
250    /// Allows reading from any node (leader, follower, or candidate) without
251    /// additional consistency checks. May return stale data but provides
252    /// best read performance and availability. Suitable for scenarios where
253    /// eventual consistency is acceptable.
254    EventualConsistency = 2,
255}
256impl ReadConsistencyPolicy {
257    /// String value of the enum field names used in the ProtoBuf definition.
258    ///
259    /// The values are not transformed in any way and thus are considered stable
260    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
261    pub fn as_str_name(&self) -> &'static str {
262        match self {
263            Self::LeaseRead => "READ_CONSISTENCY_POLICY_LEASE_READ",
264            Self::LinearizableRead => "READ_CONSISTENCY_POLICY_LINEARIZABLE_READ",
265            Self::EventualConsistency => "READ_CONSISTENCY_POLICY_EVENTUAL_CONSISTENCY",
266        }
267    }
268    /// Creates an enum from field names used in the ProtoBuf definition.
269    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
270        match value {
271            "READ_CONSISTENCY_POLICY_LEASE_READ" => Some(Self::LeaseRead),
272            "READ_CONSISTENCY_POLICY_LINEARIZABLE_READ" => Some(Self::LinearizableRead),
273            "READ_CONSISTENCY_POLICY_EVENTUAL_CONSISTENCY" => {
274                Some(Self::EventualConsistency)
275            }
276            _ => None,
277        }
278    }
279}
280/// Watch event type indicating the type of change that occurred
281#[derive(serde::Serialize, serde::Deserialize)]
282#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
283#[repr(i32)]
284pub enum WatchEventType {
285    /// A key was inserted or updated
286    Put = 0,
287    /// A key was explicitly deleted
288    Delete = 1,
289    /// Watcher forcibly canceled by the server (e.g. buffer overflow).
290    /// Client should re-sync via Read API and re-register the watch.
291    Canceled = 2,
292    /// Periodic heartbeat with no data change.
293    /// Carries current revision so clients can confirm the stream is alive.
294    Progress = 3,
295}
296impl WatchEventType {
297    /// String value of the enum field names used in the ProtoBuf definition.
298    ///
299    /// The values are not transformed in any way and thus are considered stable
300    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
301    pub fn as_str_name(&self) -> &'static str {
302        match self {
303            Self::Put => "WATCH_EVENT_TYPE_PUT",
304            Self::Delete => "WATCH_EVENT_TYPE_DELETE",
305            Self::Canceled => "WATCH_EVENT_TYPE_CANCELED",
306            Self::Progress => "WATCH_EVENT_TYPE_PROGRESS",
307        }
308    }
309    /// Creates an enum from field names used in the ProtoBuf definition.
310    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
311        match value {
312            "WATCH_EVENT_TYPE_PUT" => Some(Self::Put),
313            "WATCH_EVENT_TYPE_DELETE" => Some(Self::Delete),
314            "WATCH_EVENT_TYPE_CANCELED" => Some(Self::Canceled),
315            "WATCH_EVENT_TYPE_PROGRESS" => Some(Self::Progress),
316            _ => None,
317        }
318    }
319}
320/// Generated client implementations.
321pub mod raft_client_service_client {
322    #![allow(
323        unused_variables,
324        dead_code,
325        missing_docs,
326        clippy::wildcard_imports,
327        clippy::let_unit_value,
328    )]
329    use tonic::codegen::*;
330    use tonic::codegen::http::Uri;
331    #[derive(Debug, Clone)]
332    pub struct RaftClientServiceClient<T> {
333        inner: tonic::client::Grpc<T>,
334    }
335    impl RaftClientServiceClient<tonic::transport::Channel> {
336        /// Attempt to create a new client by connecting to a given endpoint.
337        pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error>
338        where
339            D: TryInto<tonic::transport::Endpoint>,
340            D::Error: Into<StdError>,
341        {
342            let conn = tonic::transport::Endpoint::new(dst)?.connect().await?;
343            Ok(Self::new(conn))
344        }
345    }
346    impl<T> RaftClientServiceClient<T>
347    where
348        T: tonic::client::GrpcService<tonic::body::Body>,
349        T::Error: Into<StdError>,
350        T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static,
351        <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send,
352    {
353        pub fn new(inner: T) -> Self {
354            let inner = tonic::client::Grpc::new(inner);
355            Self { inner }
356        }
357        pub fn with_origin(inner: T, origin: Uri) -> Self {
358            let inner = tonic::client::Grpc::with_origin(inner, origin);
359            Self { inner }
360        }
361        pub fn with_interceptor<F>(
362            inner: T,
363            interceptor: F,
364        ) -> RaftClientServiceClient<InterceptedService<T, F>>
365        where
366            F: tonic::service::Interceptor,
367            T::ResponseBody: Default,
368            T: tonic::codegen::Service<
369                http::Request<tonic::body::Body>,
370                Response = http::Response<
371                    <T as tonic::client::GrpcService<tonic::body::Body>>::ResponseBody,
372                >,
373            >,
374            <T as tonic::codegen::Service<
375                http::Request<tonic::body::Body>,
376            >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync,
377        {
378            RaftClientServiceClient::new(InterceptedService::new(inner, interceptor))
379        }
380        /// Compress requests with the given encoding.
381        ///
382        /// This requires the server to support it otherwise it might respond with an
383        /// error.
384        #[must_use]
385        pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {
386            self.inner = self.inner.send_compressed(encoding);
387            self
388        }
389        /// Enable decompressing responses.
390        #[must_use]
391        pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {
392            self.inner = self.inner.accept_compressed(encoding);
393            self
394        }
395        /// Limits the maximum size of a decoded message.
396        ///
397        /// Default: `4MB`
398        #[must_use]
399        pub fn max_decoding_message_size(mut self, limit: usize) -> Self {
400            self.inner = self.inner.max_decoding_message_size(limit);
401            self
402        }
403        /// Limits the maximum size of an encoded message.
404        ///
405        /// Default: `usize::MAX`
406        #[must_use]
407        pub fn max_encoding_message_size(mut self, limit: usize) -> Self {
408            self.inner = self.inner.max_encoding_message_size(limit);
409            self
410        }
411        pub async fn handle_client_write(
412            &mut self,
413            request: impl tonic::IntoRequest<super::ClientWriteRequest>,
414        ) -> std::result::Result<tonic::Response<super::ClientResponse>, tonic::Status> {
415            self.inner
416                .ready()
417                .await
418                .map_err(|e| {
419                    tonic::Status::unknown(
420                        format!("Service was not ready: {}", e.into()),
421                    )
422                })?;
423            let codec = tonic::codec::ProstCodec::default();
424            let path = http::uri::PathAndQuery::from_static(
425                "/d_engine.client.RaftClientService/HandleClientWrite",
426            );
427            let mut req = request.into_request();
428            req.extensions_mut()
429                .insert(
430                    GrpcMethod::new(
431                        "d_engine.client.RaftClientService",
432                        "HandleClientWrite",
433                    ),
434                );
435            self.inner.unary(req, path, codec).await
436        }
437        pub async fn handle_client_read(
438            &mut self,
439            request: impl tonic::IntoRequest<super::ClientReadRequest>,
440        ) -> std::result::Result<tonic::Response<super::ClientResponse>, tonic::Status> {
441            self.inner
442                .ready()
443                .await
444                .map_err(|e| {
445                    tonic::Status::unknown(
446                        format!("Service was not ready: {}", e.into()),
447                    )
448                })?;
449            let codec = tonic::codec::ProstCodec::default();
450            let path = http::uri::PathAndQuery::from_static(
451                "/d_engine.client.RaftClientService/HandleClientRead",
452            );
453            let mut req = request.into_request();
454            req.extensions_mut()
455                .insert(
456                    GrpcMethod::new(
457                        "d_engine.client.RaftClientService",
458                        "HandleClientRead",
459                    ),
460                );
461            self.inner.unary(req, path, codec).await
462        }
463        pub async fn handle_client_scan(
464            &mut self,
465            request: impl tonic::IntoRequest<super::ScanRequest>,
466        ) -> std::result::Result<tonic::Response<super::ScanResponse>, tonic::Status> {
467            self.inner
468                .ready()
469                .await
470                .map_err(|e| {
471                    tonic::Status::unknown(
472                        format!("Service was not ready: {}", e.into()),
473                    )
474                })?;
475            let codec = tonic::codec::ProstCodec::default();
476            let path = http::uri::PathAndQuery::from_static(
477                "/d_engine.client.RaftClientService/HandleClientScan",
478            );
479            let mut req = request.into_request();
480            req.extensions_mut()
481                .insert(
482                    GrpcMethod::new(
483                        "d_engine.client.RaftClientService",
484                        "HandleClientScan",
485                    ),
486                );
487            self.inner.unary(req, path, codec).await
488        }
489        /// Watch for changes to a specific key.
490        ///
491        /// Returns a stream of WatchResponse events whenever the watched key changes.
492        /// The stream remains open until the client cancels or disconnects.
493        ///
494        /// Performance characteristics:
495        /// - Event notification latency: typically < 100μs
496        /// - Minimal overhead on write path (< 0.01% with 100+ watchers)
497        ///
498        /// Error handling:
499        /// - If the internal event buffer is full, events may be dropped
500        /// - Clients should use Read API to re-sync if they detect gaps
501        pub async fn watch(
502            &mut self,
503            request: impl tonic::IntoRequest<super::WatchRequest>,
504        ) -> std::result::Result<
505            tonic::Response<tonic::codec::Streaming<super::WatchResponse>>,
506            tonic::Status,
507        > {
508            self.inner
509                .ready()
510                .await
511                .map_err(|e| {
512                    tonic::Status::unknown(
513                        format!("Service was not ready: {}", e.into()),
514                    )
515                })?;
516            let codec = tonic::codec::ProstCodec::default();
517            let path = http::uri::PathAndQuery::from_static(
518                "/d_engine.client.RaftClientService/Watch",
519            );
520            let mut req = request.into_request();
521            req.extensions_mut()
522                .insert(GrpcMethod::new("d_engine.client.RaftClientService", "Watch"));
523            self.inner.server_streaming(req, path, codec).await
524        }
525        /// Watch for committed cluster membership changes.
526        ///
527        /// Immediately pushes the current MembershipSnapshot on connect, then pushes
528        /// a new snapshot on every committed ConfChange (AddNode, BatchPromote, BatchRemove).
529        /// All nodes (leader, follower, learner) emit the event after the entry commits.
530        ///
531        /// Stream lifecycle:
532        /// - Stays open until the client cancels or the server shuts down.
533        /// - On server shutdown the stream closes with Status::UNAVAILABLE.
534        ///   Clients should reconnect and re-subscribe.
535        ///
536        /// Idempotency:
537        /// - Use `committed_index` as an idempotency key in the receiver.
538        pub async fn watch_membership(
539            &mut self,
540            request: impl tonic::IntoRequest<super::WatchMembershipRequest>,
541        ) -> std::result::Result<
542            tonic::Response<tonic::codec::Streaming<super::MembershipSnapshot>>,
543            tonic::Status,
544        > {
545            self.inner
546                .ready()
547                .await
548                .map_err(|e| {
549                    tonic::Status::unknown(
550                        format!("Service was not ready: {}", e.into()),
551                    )
552                })?;
553            let codec = tonic::codec::ProstCodec::default();
554            let path = http::uri::PathAndQuery::from_static(
555                "/d_engine.client.RaftClientService/WatchMembership",
556            );
557            let mut req = request.into_request();
558            req.extensions_mut()
559                .insert(
560                    GrpcMethod::new(
561                        "d_engine.client.RaftClientService",
562                        "WatchMembership",
563                    ),
564                );
565            self.inner.server_streaming(req, path, codec).await
566        }
567    }
568}
569/// Generated server implementations.
570pub mod raft_client_service_server {
571    #![allow(
572        unused_variables,
573        dead_code,
574        missing_docs,
575        clippy::wildcard_imports,
576        clippy::let_unit_value,
577    )]
578    use tonic::codegen::*;
579    /// Generated trait containing gRPC methods that should be implemented for use with RaftClientServiceServer.
580    #[async_trait]
581    pub trait RaftClientService: std::marker::Send + std::marker::Sync + 'static {
582        async fn handle_client_write(
583            &self,
584            request: tonic::Request<super::ClientWriteRequest>,
585        ) -> std::result::Result<tonic::Response<super::ClientResponse>, tonic::Status>;
586        async fn handle_client_read(
587            &self,
588            request: tonic::Request<super::ClientReadRequest>,
589        ) -> std::result::Result<tonic::Response<super::ClientResponse>, tonic::Status>;
590        async fn handle_client_scan(
591            &self,
592            request: tonic::Request<super::ScanRequest>,
593        ) -> std::result::Result<tonic::Response<super::ScanResponse>, tonic::Status>;
594        /// Server streaming response type for the Watch method.
595        type WatchStream: tonic::codegen::tokio_stream::Stream<
596                Item = std::result::Result<super::WatchResponse, tonic::Status>,
597            >
598            + std::marker::Send
599            + 'static;
600        /// Watch for changes to a specific key.
601        ///
602        /// Returns a stream of WatchResponse events whenever the watched key changes.
603        /// The stream remains open until the client cancels or disconnects.
604        ///
605        /// Performance characteristics:
606        /// - Event notification latency: typically < 100μs
607        /// - Minimal overhead on write path (< 0.01% with 100+ watchers)
608        ///
609        /// Error handling:
610        /// - If the internal event buffer is full, events may be dropped
611        /// - Clients should use Read API to re-sync if they detect gaps
612        async fn watch(
613            &self,
614            request: tonic::Request<super::WatchRequest>,
615        ) -> std::result::Result<tonic::Response<Self::WatchStream>, tonic::Status>;
616        /// Server streaming response type for the WatchMembership method.
617        type WatchMembershipStream: tonic::codegen::tokio_stream::Stream<
618                Item = std::result::Result<super::MembershipSnapshot, tonic::Status>,
619            >
620            + std::marker::Send
621            + 'static;
622        /// Watch for committed cluster membership changes.
623        ///
624        /// Immediately pushes the current MembershipSnapshot on connect, then pushes
625        /// a new snapshot on every committed ConfChange (AddNode, BatchPromote, BatchRemove).
626        /// All nodes (leader, follower, learner) emit the event after the entry commits.
627        ///
628        /// Stream lifecycle:
629        /// - Stays open until the client cancels or the server shuts down.
630        /// - On server shutdown the stream closes with Status::UNAVAILABLE.
631        ///   Clients should reconnect and re-subscribe.
632        ///
633        /// Idempotency:
634        /// - Use `committed_index` as an idempotency key in the receiver.
635        async fn watch_membership(
636            &self,
637            request: tonic::Request<super::WatchMembershipRequest>,
638        ) -> std::result::Result<
639            tonic::Response<Self::WatchMembershipStream>,
640            tonic::Status,
641        >;
642    }
643    #[derive(Debug)]
644    pub struct RaftClientServiceServer<T> {
645        inner: Arc<T>,
646        accept_compression_encodings: EnabledCompressionEncodings,
647        send_compression_encodings: EnabledCompressionEncodings,
648        max_decoding_message_size: Option<usize>,
649        max_encoding_message_size: Option<usize>,
650    }
651    impl<T> RaftClientServiceServer<T> {
652        pub fn new(inner: T) -> Self {
653            Self::from_arc(Arc::new(inner))
654        }
655        pub fn from_arc(inner: Arc<T>) -> Self {
656            Self {
657                inner,
658                accept_compression_encodings: Default::default(),
659                send_compression_encodings: Default::default(),
660                max_decoding_message_size: None,
661                max_encoding_message_size: None,
662            }
663        }
664        pub fn with_interceptor<F>(
665            inner: T,
666            interceptor: F,
667        ) -> InterceptedService<Self, F>
668        where
669            F: tonic::service::Interceptor,
670        {
671            InterceptedService::new(Self::new(inner), interceptor)
672        }
673        /// Enable decompressing requests with the given encoding.
674        #[must_use]
675        pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {
676            self.accept_compression_encodings.enable(encoding);
677            self
678        }
679        /// Compress responses with the given encoding, if the client supports it.
680        #[must_use]
681        pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {
682            self.send_compression_encodings.enable(encoding);
683            self
684        }
685        /// Limits the maximum size of a decoded message.
686        ///
687        /// Default: `4MB`
688        #[must_use]
689        pub fn max_decoding_message_size(mut self, limit: usize) -> Self {
690            self.max_decoding_message_size = Some(limit);
691            self
692        }
693        /// Limits the maximum size of an encoded message.
694        ///
695        /// Default: `usize::MAX`
696        #[must_use]
697        pub fn max_encoding_message_size(mut self, limit: usize) -> Self {
698            self.max_encoding_message_size = Some(limit);
699            self
700        }
701    }
702    impl<T, B> tonic::codegen::Service<http::Request<B>> for RaftClientServiceServer<T>
703    where
704        T: RaftClientService,
705        B: Body + std::marker::Send + 'static,
706        B::Error: Into<StdError> + std::marker::Send + 'static,
707    {
708        type Response = http::Response<tonic::body::Body>;
709        type Error = std::convert::Infallible;
710        type Future = BoxFuture<Self::Response, Self::Error>;
711        fn poll_ready(
712            &mut self,
713            _cx: &mut Context<'_>,
714        ) -> Poll<std::result::Result<(), Self::Error>> {
715            Poll::Ready(Ok(()))
716        }
717        fn call(&mut self, req: http::Request<B>) -> Self::Future {
718            match req.uri().path() {
719                "/d_engine.client.RaftClientService/HandleClientWrite" => {
720                    #[allow(non_camel_case_types)]
721                    struct HandleClientWriteSvc<T: RaftClientService>(pub Arc<T>);
722                    impl<
723                        T: RaftClientService,
724                    > tonic::server::UnaryService<super::ClientWriteRequest>
725                    for HandleClientWriteSvc<T> {
726                        type Response = super::ClientResponse;
727                        type Future = BoxFuture<
728                            tonic::Response<Self::Response>,
729                            tonic::Status,
730                        >;
731                        fn call(
732                            &mut self,
733                            request: tonic::Request<super::ClientWriteRequest>,
734                        ) -> Self::Future {
735                            let inner = Arc::clone(&self.0);
736                            let fut = async move {
737                                <T as RaftClientService>::handle_client_write(
738                                        &inner,
739                                        request,
740                                    )
741                                    .await
742                            };
743                            Box::pin(fut)
744                        }
745                    }
746                    let accept_compression_encodings = self.accept_compression_encodings;
747                    let send_compression_encodings = self.send_compression_encodings;
748                    let max_decoding_message_size = self.max_decoding_message_size;
749                    let max_encoding_message_size = self.max_encoding_message_size;
750                    let inner = self.inner.clone();
751                    let fut = async move {
752                        let method = HandleClientWriteSvc(inner);
753                        let codec = tonic::codec::ProstCodec::default();
754                        let mut grpc = tonic::server::Grpc::new(codec)
755                            .apply_compression_config(
756                                accept_compression_encodings,
757                                send_compression_encodings,
758                            )
759                            .apply_max_message_size_config(
760                                max_decoding_message_size,
761                                max_encoding_message_size,
762                            );
763                        let res = grpc.unary(method, req).await;
764                        Ok(res)
765                    };
766                    Box::pin(fut)
767                }
768                "/d_engine.client.RaftClientService/HandleClientRead" => {
769                    #[allow(non_camel_case_types)]
770                    struct HandleClientReadSvc<T: RaftClientService>(pub Arc<T>);
771                    impl<
772                        T: RaftClientService,
773                    > tonic::server::UnaryService<super::ClientReadRequest>
774                    for HandleClientReadSvc<T> {
775                        type Response = super::ClientResponse;
776                        type Future = BoxFuture<
777                            tonic::Response<Self::Response>,
778                            tonic::Status,
779                        >;
780                        fn call(
781                            &mut self,
782                            request: tonic::Request<super::ClientReadRequest>,
783                        ) -> Self::Future {
784                            let inner = Arc::clone(&self.0);
785                            let fut = async move {
786                                <T as RaftClientService>::handle_client_read(
787                                        &inner,
788                                        request,
789                                    )
790                                    .await
791                            };
792                            Box::pin(fut)
793                        }
794                    }
795                    let accept_compression_encodings = self.accept_compression_encodings;
796                    let send_compression_encodings = self.send_compression_encodings;
797                    let max_decoding_message_size = self.max_decoding_message_size;
798                    let max_encoding_message_size = self.max_encoding_message_size;
799                    let inner = self.inner.clone();
800                    let fut = async move {
801                        let method = HandleClientReadSvc(inner);
802                        let codec = tonic::codec::ProstCodec::default();
803                        let mut grpc = tonic::server::Grpc::new(codec)
804                            .apply_compression_config(
805                                accept_compression_encodings,
806                                send_compression_encodings,
807                            )
808                            .apply_max_message_size_config(
809                                max_decoding_message_size,
810                                max_encoding_message_size,
811                            );
812                        let res = grpc.unary(method, req).await;
813                        Ok(res)
814                    };
815                    Box::pin(fut)
816                }
817                "/d_engine.client.RaftClientService/HandleClientScan" => {
818                    #[allow(non_camel_case_types)]
819                    struct HandleClientScanSvc<T: RaftClientService>(pub Arc<T>);
820                    impl<
821                        T: RaftClientService,
822                    > tonic::server::UnaryService<super::ScanRequest>
823                    for HandleClientScanSvc<T> {
824                        type Response = super::ScanResponse;
825                        type Future = BoxFuture<
826                            tonic::Response<Self::Response>,
827                            tonic::Status,
828                        >;
829                        fn call(
830                            &mut self,
831                            request: tonic::Request<super::ScanRequest>,
832                        ) -> Self::Future {
833                            let inner = Arc::clone(&self.0);
834                            let fut = async move {
835                                <T as RaftClientService>::handle_client_scan(
836                                        &inner,
837                                        request,
838                                    )
839                                    .await
840                            };
841                            Box::pin(fut)
842                        }
843                    }
844                    let accept_compression_encodings = self.accept_compression_encodings;
845                    let send_compression_encodings = self.send_compression_encodings;
846                    let max_decoding_message_size = self.max_decoding_message_size;
847                    let max_encoding_message_size = self.max_encoding_message_size;
848                    let inner = self.inner.clone();
849                    let fut = async move {
850                        let method = HandleClientScanSvc(inner);
851                        let codec = tonic::codec::ProstCodec::default();
852                        let mut grpc = tonic::server::Grpc::new(codec)
853                            .apply_compression_config(
854                                accept_compression_encodings,
855                                send_compression_encodings,
856                            )
857                            .apply_max_message_size_config(
858                                max_decoding_message_size,
859                                max_encoding_message_size,
860                            );
861                        let res = grpc.unary(method, req).await;
862                        Ok(res)
863                    };
864                    Box::pin(fut)
865                }
866                "/d_engine.client.RaftClientService/Watch" => {
867                    #[allow(non_camel_case_types)]
868                    struct WatchSvc<T: RaftClientService>(pub Arc<T>);
869                    impl<
870                        T: RaftClientService,
871                    > tonic::server::ServerStreamingService<super::WatchRequest>
872                    for WatchSvc<T> {
873                        type Response = super::WatchResponse;
874                        type ResponseStream = T::WatchStream;
875                        type Future = BoxFuture<
876                            tonic::Response<Self::ResponseStream>,
877                            tonic::Status,
878                        >;
879                        fn call(
880                            &mut self,
881                            request: tonic::Request<super::WatchRequest>,
882                        ) -> Self::Future {
883                            let inner = Arc::clone(&self.0);
884                            let fut = async move {
885                                <T as RaftClientService>::watch(&inner, request).await
886                            };
887                            Box::pin(fut)
888                        }
889                    }
890                    let accept_compression_encodings = self.accept_compression_encodings;
891                    let send_compression_encodings = self.send_compression_encodings;
892                    let max_decoding_message_size = self.max_decoding_message_size;
893                    let max_encoding_message_size = self.max_encoding_message_size;
894                    let inner = self.inner.clone();
895                    let fut = async move {
896                        let method = WatchSvc(inner);
897                        let codec = tonic::codec::ProstCodec::default();
898                        let mut grpc = tonic::server::Grpc::new(codec)
899                            .apply_compression_config(
900                                accept_compression_encodings,
901                                send_compression_encodings,
902                            )
903                            .apply_max_message_size_config(
904                                max_decoding_message_size,
905                                max_encoding_message_size,
906                            );
907                        let res = grpc.server_streaming(method, req).await;
908                        Ok(res)
909                    };
910                    Box::pin(fut)
911                }
912                "/d_engine.client.RaftClientService/WatchMembership" => {
913                    #[allow(non_camel_case_types)]
914                    struct WatchMembershipSvc<T: RaftClientService>(pub Arc<T>);
915                    impl<
916                        T: RaftClientService,
917                    > tonic::server::ServerStreamingService<
918                        super::WatchMembershipRequest,
919                    > for WatchMembershipSvc<T> {
920                        type Response = super::MembershipSnapshot;
921                        type ResponseStream = T::WatchMembershipStream;
922                        type Future = BoxFuture<
923                            tonic::Response<Self::ResponseStream>,
924                            tonic::Status,
925                        >;
926                        fn call(
927                            &mut self,
928                            request: tonic::Request<super::WatchMembershipRequest>,
929                        ) -> Self::Future {
930                            let inner = Arc::clone(&self.0);
931                            let fut = async move {
932                                <T as RaftClientService>::watch_membership(&inner, request)
933                                    .await
934                            };
935                            Box::pin(fut)
936                        }
937                    }
938                    let accept_compression_encodings = self.accept_compression_encodings;
939                    let send_compression_encodings = self.send_compression_encodings;
940                    let max_decoding_message_size = self.max_decoding_message_size;
941                    let max_encoding_message_size = self.max_encoding_message_size;
942                    let inner = self.inner.clone();
943                    let fut = async move {
944                        let method = WatchMembershipSvc(inner);
945                        let codec = tonic::codec::ProstCodec::default();
946                        let mut grpc = tonic::server::Grpc::new(codec)
947                            .apply_compression_config(
948                                accept_compression_encodings,
949                                send_compression_encodings,
950                            )
951                            .apply_max_message_size_config(
952                                max_decoding_message_size,
953                                max_encoding_message_size,
954                            );
955                        let res = grpc.server_streaming(method, req).await;
956                        Ok(res)
957                    };
958                    Box::pin(fut)
959                }
960                _ => {
961                    Box::pin(async move {
962                        let mut response = http::Response::new(
963                            tonic::body::Body::default(),
964                        );
965                        let headers = response.headers_mut();
966                        headers
967                            .insert(
968                                tonic::Status::GRPC_STATUS,
969                                (tonic::Code::Unimplemented as i32).into(),
970                            );
971                        headers
972                            .insert(
973                                http::header::CONTENT_TYPE,
974                                tonic::metadata::GRPC_CONTENT_TYPE,
975                            );
976                        Ok(response)
977                    })
978                }
979            }
980        }
981    }
982    impl<T> Clone for RaftClientServiceServer<T> {
983        fn clone(&self) -> Self {
984            let inner = self.inner.clone();
985            Self {
986                inner,
987                accept_compression_encodings: self.accept_compression_encodings,
988                send_compression_encodings: self.send_compression_encodings,
989                max_decoding_message_size: self.max_decoding_message_size,
990                max_encoding_message_size: self.max_encoding_message_size,
991            }
992        }
993    }
994    /// Generated gRPC service name
995    pub const SERVICE_NAME: &str = "d_engine.client.RaftClientService";
996    impl<T> tonic::server::NamedService for RaftClientServiceServer<T> {
997        const NAME: &'static str = SERVICE_NAME;
998    }
999}