Skip to main content

grpc/
server.rs

1//! Caller-thread HTTP/2 service routing and typed request/response streams.
2use std::{
3    cell::{Cell, RefCell},
4    collections::{BTreeMap, BTreeSet, VecDeque},
5    io,
6    panic::{AssertUnwindSafe, catch_unwind},
7    rc::Rc,
8    time::{Duration, Instant},
9};
10
11use grpc_core::{
12    Codec, Metadata, Request, Response, Status,
13    compression::CompressionAlgorithm,
14    session::{GrpcServerSession, IncomingRequest, SessionConfig},
15    transport::SyncTransport,
16};
17
18use crate::stream::{RequestStream, ResponseSink, StreamDriver, StreamError, server_streams};
19
20fn normalized_content_type(value: &str) -> &str {
21    if value == "application/grpc+proto" {
22        "application/grpc"
23    } else {
24        value
25    }
26}
27fn io_status(error: io::Error) -> Status {
28    Status::unavailable(error.to_string())
29}
30fn stream_status(error: StreamError) -> Status {
31    match error {
32        StreamError::Status(status) => status,
33        StreamError::WouldBlock => Status::internal("blocking stream operation remained pending"),
34    }
35}
36struct ServerInner<T> {
37    session: GrpcServerSession,
38    transport: T,
39    buffer: Vec<u8>,
40    pending_incoming: VecDeque<(Instant, IncomingRequest)>,
41    pending_reap: BTreeSet<i32>,
42    reset_reap: BTreeSet<i32>,
43    closed: bool,
44    draining: bool,
45}
46impl<T: SyncTransport> ServerInner<T> {
47    fn drive(&mut self, blocking: bool, deadline: Option<Instant>) -> Result<usize, Status> {
48        let remaining = |deadline: Option<Instant>| -> Result<Option<Duration>, Status> {
49            let timeout = deadline.map(|at| at.saturating_duration_since(Instant::now()));
50            if timeout.is_some_and(|duration| duration.is_zero()) {
51                Err(Status::deadline_exceeded("request deadline elapsed"))
52            } else {
53                Ok(timeout)
54            }
55        };
56        remaining(deadline)?;
57        self.transport.set_nonblocking(true).map_err(io_status)?;
58        self.flush()?;
59        let mut result = loop {
60            match self.transport.read(&mut self.buffer) {
61                Err(error) if error.kind() == io::ErrorKind::Interrupted => {
62                    remaining(deadline)?;
63                }
64                result => break result,
65            }
66        };
67        if blocking && matches!(&result, Err(error) if error.kind() == io::ErrorKind::WouldBlock) {
68            self.transport.set_nonblocking(false).map_err(io_status)?;
69            let waited = (|| -> Result<_, Status> {
70                loop {
71                    let mut timeout = remaining(deadline)?;
72                    if self.session.want_write() || !self.pending_reap.is_empty() {
73                        let quantum = Duration::from_millis(1);
74                        timeout = Some(timeout.map_or(quantum, |left| left.min(quantum)));
75                    }
76                    self.transport
77                        .set_read_timeout(timeout)
78                        .map_err(io_status)?;
79                    match self.transport.read(&mut self.buffer) {
80                        Err(error) if error.kind() == io::ErrorKind::Interrupted => continue,
81                        result => return Ok(result),
82                    }
83                }
84            })();
85            self.transport.set_nonblocking(true).map_err(io_status)?;
86            result = waited?;
87        }
88        let count = match result {
89            Ok(0) => {
90                remaining(deadline)?;
91                self.closed = true;
92                return Ok(0);
93            }
94            Ok(count) => count,
95            Err(error)
96                if matches!(
97                    error.kind(),
98                    io::ErrorKind::WouldBlock | io::ErrorKind::TimedOut
99                ) =>
100            {
101                remaining(deadline)?;
102                return Ok(0);
103            }
104            Err(error) => {
105                remaining(deadline)?;
106                return Err(io_status(error));
107            }
108        };
109        let mut offset = 0;
110        while offset < count {
111            let used = self.session.mem_recv(&self.buffer[offset..count])?;
112            if used == 0 {
113                return Err(Status::internal("HTTP/2 receive made no progress"));
114            }
115            offset += used;
116            while let Some(request) = self.session.pop_incoming_request() {
117                self.pending_incoming.push_back((Instant::now(), request));
118            }
119        }
120        self.flush()?;
121        remaining(deadline)?;
122        Ok(count)
123    }
124    fn flush(&mut self) -> Result<(), Status> {
125        self.transport.set_nonblocking(true).map_err(io_status)?;
126        self.session.flush_to_transport(&mut self.transport)?;
127        self.session.reap_closed_undispatched_streams()?;
128        let ready: Vec<_> = self
129            .pending_reap
130            .iter()
131            .copied()
132            .filter(|id| self.session.stream_outbound_complete(*id))
133            .collect();
134        for id in ready {
135            if !self.reset_reap.contains(&id) {
136                match self.session.is_remote_end_stream(id) {
137                    Ok(false) => {
138                        self.session.cancel_stream(id, 0)?;
139                        self.reset_reap.insert(id);
140                        self.session.flush_to_transport(&mut self.transport)?;
141                    }
142                    Ok(true) => {}
143                    Err(_) => {
144                        self.reset_reap.insert(id);
145                    }
146                }
147            }
148            match self.session.remove_closed_stream(id) {
149                Ok(()) => {}
150                Err(error) if error.code() == grpc_core::Code::FailedPrecondition => continue,
151                Err(error) => return Err(error),
152            }
153            self.pending_reap.remove(&id);
154            self.reset_reap.remove(&id);
155        }
156        Ok(())
157    }
158}
159
160/// Raw payload codec for custom service dispatchers.
161#[derive(Default)]
162pub struct PayloadCodec;
163impl Codec for PayloadCodec {
164    type EncodeItem = Vec<u8>;
165    type DecodeItem = Vec<u8>;
166    type Error = Status;
167    const CONTENT_TYPE: &'static str = "application/grpc";
168    fn encode(&mut self, item: &Vec<u8>, destination: &mut Vec<u8>) -> Result<(), Status> {
169        destination.extend_from_slice(item);
170        Ok(())
171    }
172    fn decode(&mut self, payload: &[u8]) -> Result<Vec<u8>, Status> {
173        Ok(payload.to_vec())
174    }
175}
176
177/// Custom dispatcher receiving raw request payloads and a raw response sink.
178/// Implementations can bridge generated service methods using their descriptors.
179pub trait ServiceHandler {
180    /// Runs one routed RPC. The server sends terminal status after this returns.
181    /// # Errors
182    /// Returns the RPC status to send to the caller.
183    fn handle(
184        &mut self,
185        requests: RequestStream<Vec<u8>>,
186        responses: &mut ResponseSink<Vec<u8>>,
187    ) -> Result<(), Status>;
188}
189impl<F> ServiceHandler for F
190where
191    F: FnMut(RequestStream<Vec<u8>>, &mut ResponseSink<Vec<u8>>) -> Result<(), Status>,
192{
193    fn handle(
194        &mut self,
195        requests: RequestStream<Vec<u8>>,
196        responses: &mut ResponseSink<Vec<u8>>,
197    ) -> Result<(), Status> {
198        self(requests, responses)
199    }
200}
201
202/// Typed stream driver sharing a single caller-thread server connection.
203pub struct ServerStreamDriver<T: SyncTransport, C: Codec> {
204    inner: Rc<RefCell<ServerInner<T>>>,
205    codec: Rc<RefCell<C>>,
206    id: i32,
207    deadline: Option<Instant>,
208    initial: Metadata,
209    trailers: Option<Metadata>,
210    encoding: CompressionAlgorithm,
211    response_initial_sent: bool,
212    complete: Rc<Cell<bool>>,
213}
214impl<T: SyncTransport, C: Codec> ServerStreamDriver<T, C> {
215    fn check_deadline(&self) -> Result<(), StreamError> {
216        if !self.deadline.is_some_and(|at| Instant::now() >= at) {
217            return Ok(());
218        }
219        let status = Status::deadline_exceeded("request deadline elapsed");
220        if !self.complete.get() {
221            let mut inner = self
222                .inner
223                .try_borrow_mut()
224                .map_err(|_| Status::failed_precondition("reentrant server operation"))?;
225            inner.transport.set_nonblocking(true).map_err(io_status)?;
226            inner
227                .session
228                .finish_response(self.id, &status, &Metadata::new())?;
229            self.complete.set(true);
230            inner.pending_reap.insert(self.id);
231            inner.flush()?;
232        }
233        Err(status.into())
234    }
235}
236impl<T: SyncTransport, C: Codec> StreamDriver for ServerStreamDriver<T, C>
237where
238    C::EncodeItem: Sized,
239{
240    type Send = C::EncodeItem;
241    type Receive = C::DecodeItem;
242    fn send(&mut self, message: &Self::Send) -> Result<(), StreamError> {
243        self.check_deadline()?;
244        let mut bytes = Vec::new();
245        self.codec
246            .try_borrow_mut()
247            .map_err(|_| Status::failed_precondition("reentrant codec"))?
248            .encode(message, &mut bytes)
249            .map_err(|error| Status::internal(error.to_string()))?;
250        self.check_deadline()?;
251        let mut inner = self
252            .inner
253            .try_borrow_mut()
254            .map_err(|_| Status::failed_precondition("reentrant server operation"))?;
255        inner.transport.set_nonblocking(true).map_err(io_status)?;
256        if !self.response_initial_sent {
257            inner.session.send_initial_metadata_with_content_type(
258                self.id,
259                &Metadata::new(),
260                self.encoding,
261                C::CONTENT_TYPE,
262            )?;
263            self.response_initial_sent = true;
264        }
265        inner.session.send_message(self.id, &bytes, self.encoding)?;
266        inner.flush()?;
267        Ok(())
268    }
269    fn half_close(&mut self) -> Result<(), StreamError> {
270        Err(Status::failed_precondition("server responses close with final status").into())
271    }
272    fn try_recv_next(&mut self) -> Result<Option<Self::Receive>, StreamError> {
273        self.check_deadline()?;
274        let mut inner = self
275            .inner
276            .try_borrow_mut()
277            .map_err(|_| Status::failed_precondition("reentrant server operation"))?;
278        for attempt in 0..2 {
279            if let Some(message) = inner.session.pop_message(self.id)? {
280                drop(inner);
281                let value = self
282                    .codec
283                    .try_borrow_mut()
284                    .map_err(|_| Status::failed_precondition("reentrant codec"))?
285                    .decode(message.payload())
286                    .map_err(|error| Status::invalid_argument(error.to_string()))?;
287                self.check_deadline()?;
288                return Ok(Some(value));
289            }
290            if inner.session.is_remote_end_stream(self.id)? {
291                return Ok(None);
292            }
293            if attempt == 0 {
294                inner.drive(false, self.deadline)?;
295            }
296        }
297        if inner.closed {
298            Err(Status::unavailable("transport EOF during request").into())
299        } else {
300            Err(StreamError::WouldBlock)
301        }
302    }
303    fn wait_ready(&mut self) -> Result<(), StreamError> {
304        self.check_deadline()?;
305        let mut inner = self
306            .inner
307            .try_borrow_mut()
308            .map_err(|_| Status::failed_precondition("reentrant server operation"))?;
309        inner.drive(true, self.deadline)?;
310        if inner.closed {
311            Err(Status::unavailable("transport EOF during request").into())
312        } else {
313            Ok(())
314        }
315    }
316    fn finish(&mut self, status: &Status, trailers: &Metadata) -> Result<(), StreamError> {
317        self.check_deadline()?;
318        if self.complete.get() {
319            return Err(Status::failed_precondition("response already finished").into());
320        }
321        let mut inner = self
322            .inner
323            .try_borrow_mut()
324            .map_err(|_| Status::failed_precondition("reentrant server operation"))?;
325        inner.transport.set_nonblocking(true).map_err(io_status)?;
326        inner.session.finish_response(self.id, status, trailers)?;
327        self.complete.set(true);
328        inner.pending_reap.insert(self.id);
329        self.trailers = Some(trailers.clone());
330        inner.flush()?;
331        Ok(())
332    }
333    fn initial_metadata(&self) -> Option<&Metadata> {
334        Some(&self.initial)
335    }
336    fn trailing_metadata(&self) -> Option<&Metadata> {
337        self.trailers.as_ref()
338    }
339    fn cancel(&mut self) {
340        if self.deadline.is_some_and(|at| Instant::now() >= at) {
341            match self.check_deadline() {
342                Err(_) if self.complete.get() => return,
343                Err(_) | Ok(()) => {}
344            }
345        }
346        if !self.complete.get()
347            && let Ok(mut inner) = self.inner.try_borrow_mut()
348        {
349            match inner.session.cancel_stream(self.id, 8) {
350                Ok(()) => {
351                    self.complete.set(true);
352                    inner.pending_reap.insert(self.id);
353                    inner.reset_reap.insert(self.id);
354                }
355                Err(error)
356                    if matches!(
357                        error.code(),
358                        grpc_core::Code::Cancelled | grpc_core::Code::FailedPrecondition
359                    ) =>
360                {
361                    self.complete.set(true);
362                    inner.pending_reap.insert(self.id);
363                    inner.reset_reap.insert(self.id);
364                }
365                Err(error) if error.code() == grpc_core::Code::NotFound => self.complete.set(true),
366                Err(_) => inner.closed = true,
367            }
368        }
369    }
370}
371
372type DriverState<T, C> = (ServerStreamDriver<T, C>, Rc<Cell<bool>>);
373
374type Route<T> = Box<dyn FnMut(IncomingRequest, Rc<RefCell<ServerInner<T>>>) -> Result<(), Status>>;
375/// Synchronous single-connection server with path-based service registration.
376pub struct SyncServer<T: SyncTransport> {
377    inner: Rc<RefCell<ServerInner<T>>>,
378    routes: BTreeMap<String, Route<T>>,
379}
380impl<T: SyncTransport + 'static> SyncServer<T> {
381    /// Creates a server with bounded default HTTP/2 session settings.
382    /// # Errors
383    /// Returns invalid settings or native initialization failures.
384    pub fn new(transport: T) -> Result<Self, Status> {
385        Self::with_config(transport, SessionConfig::default())
386    }
387    /// Creates a connection with explicit HTTP/2 and message limits.
388    /// # Errors
389    /// Returns invalid settings or native initialization failures.
390    pub fn with_config(transport: T, config: SessionConfig) -> Result<Self, Status> {
391        Ok(Self {
392            inner: Rc::new(RefCell::new(ServerInner {
393                session: GrpcServerSession::new(config)?,
394                transport,
395                buffer: vec![0; 16 * 1024],
396                pending_incoming: VecDeque::new(),
397                pending_reap: BTreeSet::new(),
398                reset_reap: BTreeSet::new(),
399                closed: false,
400                draining: false,
401            })),
402            routes: BTreeMap::new(),
403        })
404    }
405    fn insert(&mut self, path: &str, handler: Route<T>) -> Result<(), Status> {
406        if !path.starts_with('/')
407            || path
408                .rsplit_once('/')
409                .is_none_or(|(service, method)| service.len() < 2 || method.is_empty())
410        {
411            return Err(Status::invalid_argument(
412                "RPC path must contain service and method",
413            ));
414        }
415        if self.routes.contains_key(path) {
416            return Err(Status::already_exists("RPC path is already registered"));
417        }
418        self.routes.insert(path.to_string(), handler);
419        Ok(())
420    }
421    fn streams<C: Codec>(
422        request: IncomingRequest,
423        inner: Rc<RefCell<ServerInner<T>>>,
424        codec: Rc<RefCell<C>>,
425    ) -> Result<DriverState<T, C>, Status> {
426        let content_type = request.content_type.split(';').next().unwrap_or("").trim();
427        if normalized_content_type(content_type) != normalized_content_type(C::CONTENT_TYPE) {
428            return Err(Status::unimplemented(
429                "request content type does not match registered codec",
430            ));
431        }
432        let deadline = request
433            .timeout
434            .map(|timeout| {
435                Instant::now()
436                    .checked_add(timeout)
437                    .ok_or_else(|| Status::invalid_argument("request deadline exceeds clock range"))
438            })
439            .transpose()?;
440        let encoding = if request
441            .accept_encoding
442            .split(',')
443            .any(|name| name.trim() == request.request_encoding.as_str())
444        {
445            request.request_encoding
446        } else {
447            CompressionAlgorithm::Identity
448        };
449        let complete = Rc::new(Cell::new(false));
450        Ok((
451            ServerStreamDriver {
452                inner,
453                codec,
454                id: request.stream_id,
455                deadline,
456                initial: request.initial_metadata,
457                trailers: None,
458                encoding,
459                response_initial_sent: false,
460                complete: Rc::clone(&complete),
461            },
462            complete,
463        ))
464    }
465    fn finalize<Resp>(
466        sink: &mut ResponseSink<Resp>,
467        complete: &Cell<bool>,
468        result: Result<(), Status>,
469    ) -> Result<(), Status> {
470        if complete.get() {
471            return Ok(());
472        }
473        let status = match result {
474            Ok(()) => Status::ok(""),
475            Err(status) => status,
476        };
477        let result = sink.finish(status, Metadata::new()).map_err(stream_status);
478        if complete.get() { Ok(()) } else { result }
479    }
480    /// Registers a unary handler with exactly one inbound and outbound message.
481    /// # Errors
482    /// Rejects invalid paths or duplicate registrations.
483    pub fn register_unary<C, Req, Resp, F>(
484        &mut self,
485        path: &str,
486        codec: C,
487        mut handler: F,
488    ) -> Result<(), Status>
489    where
490        C: Codec<EncodeItem = Resp, DecodeItem = Req> + 'static,
491        Req: 'static,
492        Resp: 'static,
493        F: FnMut(Request<Req>) -> Result<Response<Resp>, Status> + 'static,
494    {
495        let codec = Rc::new(RefCell::new(codec));
496        self.insert(
497            path,
498            Box::new(move |request, inner| {
499                let metadata = request.initial_metadata.clone();
500                let (mut driver, complete) =
501                    Self::streams(request, Rc::clone(&inner), Rc::clone(&codec))?;
502                driver.response_initial_sent = true;
503                let id = driver.id;
504                let encoding = driver.encoding;
505                let (mut requests, mut sink) = server_streams(driver);
506                let result = catch_unwind(AssertUnwindSafe(|| {
507                    let value = requests
508                        .recv_next()
509                        .map_err(stream_status)?
510                        .ok_or_else(|| Status::invalid_argument("unary request is missing"))?;
511                    if requests.recv_next().map_err(stream_status)?.is_some() {
512                        return Err(Status::invalid_argument(
513                            "unary request has multiple messages",
514                        ));
515                    }
516                    let response = handler(Request::from_parts(metadata, value))?;
517                    let (metadata, value) = response.into_parts();
518                    inner
519                        .borrow_mut()
520                        .session
521                        .send_initial_metadata_with_content_type(
522                            id,
523                            &metadata,
524                            encoding,
525                            C::CONTENT_TYPE,
526                        )?;
527                    sink.send(&value).map_err(stream_status)
528                }))
529                .unwrap_or_else(|_| Err(Status::internal("service handler panicked")));
530                Self::finalize(&mut sink, &complete, result)
531            }),
532        )
533    }
534    /// Registers a single-request streaming-response handler.
535    /// The server sends OK trailers if the handler has not already finished its sink.
536    /// # Errors
537    /// Rejects invalid paths or duplicate registrations.
538    pub fn register_server_streaming<C, Req, Resp, F>(
539        &mut self,
540        path: &str,
541        codec: C,
542        mut handler: F,
543    ) -> Result<(), Status>
544    where
545        C: Codec<EncodeItem = Resp, DecodeItem = Req> + 'static,
546        Req: 'static,
547        Resp: 'static,
548        F: FnMut(Request<Req>, &mut ResponseSink<Resp>) -> Result<(), Status> + 'static,
549    {
550        let codec = Rc::new(RefCell::new(codec));
551        self.insert(
552            path,
553            Box::new(move |request, inner| {
554                let metadata = request.initial_metadata.clone();
555                let (driver, complete) = Self::streams(request, inner, Rc::clone(&codec))?;
556                let (mut requests, mut sink) = server_streams(driver);
557                let result = catch_unwind(AssertUnwindSafe(|| {
558                    let value = requests
559                        .recv_next()
560                        .map_err(stream_status)?
561                        .ok_or_else(|| Status::invalid_argument("request is missing"))?;
562                    if requests.recv_next().map_err(stream_status)?.is_some() {
563                        return Err(Status::invalid_argument("request has multiple messages"));
564                    }
565                    handler(Request::from_parts(metadata, value), &mut sink)
566                }))
567                .unwrap_or_else(|_| Err(Status::internal("service handler panicked")));
568                Self::finalize(&mut sink, &complete, result)
569            }),
570        )
571    }
572    /// Registers a streaming-request handler returning exactly one response.
573    /// # Errors
574    /// Rejects invalid paths or duplicate registrations.
575    pub fn register_client_streaming<C, Req, Resp, F>(
576        &mut self,
577        path: &str,
578        codec: C,
579        mut handler: F,
580    ) -> Result<(), Status>
581    where
582        C: Codec<EncodeItem = Resp, DecodeItem = Req> + 'static,
583        Req: 'static,
584        Resp: 'static,
585        F: FnMut(RequestStream<Req>) -> Result<Response<Resp>, Status> + 'static,
586    {
587        let codec = Rc::new(RefCell::new(codec));
588        self.insert(
589            path,
590            Box::new(move |request, inner| {
591                let (mut driver, complete) =
592                    Self::streams(request, Rc::clone(&inner), Rc::clone(&codec))?;
593                driver.response_initial_sent = true;
594                let id = driver.id;
595                let encoding = driver.encoding;
596                let (requests, mut sink) = server_streams(driver);
597                let result = catch_unwind(AssertUnwindSafe(|| {
598                    let (metadata, value) = handler(requests)?.into_parts();
599                    inner
600                        .borrow_mut()
601                        .session
602                        .send_initial_metadata_with_content_type(
603                            id,
604                            &metadata,
605                            encoding,
606                            C::CONTENT_TYPE,
607                        )?;
608                    sink.send(&value).map_err(stream_status)
609                }))
610                .unwrap_or_else(|_| Err(Status::internal("service handler panicked")));
611                Self::finalize(&mut sink, &complete, result)
612            }),
613        )
614    }
615    /// Registers a bidirectional streaming handler.
616    /// # Errors
617    /// Rejects invalid paths or duplicate registrations.
618    pub fn register_bidi_streaming<C, Req, Resp, F>(
619        &mut self,
620        path: &str,
621        codec: C,
622        mut handler: F,
623    ) -> Result<(), Status>
624    where
625        C: Codec<EncodeItem = Resp, DecodeItem = Req> + 'static,
626        Req: 'static,
627        Resp: 'static,
628        F: FnMut(RequestStream<Req>, &mut ResponseSink<Resp>) -> Result<(), Status> + 'static,
629    {
630        let codec = Rc::new(RefCell::new(codec));
631        self.insert(
632            path,
633            Box::new(move |request, inner| {
634                let (driver, complete) = Self::streams(request, inner, Rc::clone(&codec))?;
635                let (requests, mut sink) = server_streams(driver);
636                let result = catch_unwind(AssertUnwindSafe(|| handler(requests, &mut sink)))
637                    .unwrap_or_else(|_| Err(Status::internal("service handler panicked")));
638                Self::finalize(&mut sink, &complete, result)
639            }),
640        )
641    }
642    /// Registers a raw-payload dispatcher, including generated-service adapters.
643    /// # Errors
644    /// Rejects invalid paths or duplicate registrations.
645    pub fn register_service_handler<H: ServiceHandler + 'static>(
646        &mut self,
647        path: &str,
648        mut handler: H,
649    ) -> Result<(), Status> {
650        self.register_bidi_streaming(path, PayloadCodec, move |requests, sink| {
651            handler.handle(requests, sink)
652        })
653    }
654    fn dispatch(&mut self) -> Result<bool, Status> {
655        let request = self.inner.borrow_mut().pending_incoming.pop_front();
656        let Some((received, mut request)) = request else {
657            return Ok(false);
658        };
659        request.timeout = request
660            .timeout
661            .map(|timeout| timeout.saturating_sub(received.elapsed()));
662        let id = request.stream_id;
663        if request.timeout.is_some_and(|timeout| timeout.is_zero()) {
664            let mut inner = self.inner.borrow_mut();
665            inner.session.finish_response(
666                id,
667                &Status::deadline_exceeded("request deadline elapsed"),
668                &Metadata::new(),
669            )?;
670            inner.pending_reap.insert(id);
671            inner.flush()?;
672            return Ok(true);
673        }
674        if let Some(handler) = self.routes.get_mut(&request.path) {
675            let result = handler(request, Rc::clone(&self.inner));
676            if let Err(status) = result {
677                let mut inner = self.inner.borrow_mut();
678                if inner
679                    .session
680                    .finish_response(id, &status, &Metadata::new())
681                    .is_err()
682                {
683                    inner.session.cancel_stream(id, 2)?;
684                    inner.reset_reap.insert(id);
685                }
686                inner.pending_reap.insert(id);
687            }
688        } else {
689            let mut inner = self.inner.borrow_mut();
690            inner.session.finish_response(
691                id,
692                &Status::unimplemented("RPC path is not registered"),
693                &Metadata::new(),
694            )?;
695            inner.pending_reap.insert(id);
696        }
697        self.inner.borrow_mut().flush()?;
698        Ok(true)
699    }
700    /// Advances nonblocking socket I/O and dispatches at most one synchronous handler.
701    /// A dispatched handler may wait for its request body on the calling thread.
702    /// # Errors
703    /// Returns native HTTP/2 or transport failures.
704    pub fn poll_once(&mut self) -> Result<bool, Status> {
705        self.inner
706            .borrow_mut()
707            .transport
708            .set_nonblocking(true)
709            .map_err(io_status)?;
710        if self.inner.borrow().closed {
711            return Ok(false);
712        }
713        if self.dispatch()? {
714            return Ok(true);
715        }
716        let progress = self.inner.borrow_mut().drive(false, None)? > 0;
717        Ok(self.dispatch()? || progress)
718    }
719    /// Serves until peer EOF or local graceful shutdown.
720    /// # Errors
721    /// Returns connection-level HTTP/2, transport or handler completion failures.
722    pub fn serve_connection(&mut self) -> Result<(), Status> {
723        loop {
724            if self.inner.borrow().closed {
725                return Ok(());
726            }
727            if self.dispatch()? {
728                continue;
729            }
730            {
731                let mut inner = self.inner.borrow_mut();
732                if inner.draining || inner.session.goaway_received().is_some() {
733                    inner.transport.set_nonblocking(true).map_err(io_status)?;
734                    inner.flush()?;
735                    if !inner.session.want_write() && inner.pending_reap.is_empty() {
736                        inner.closed = true;
737                        return Ok(());
738                    }
739                }
740                inner.drive(true, None)?;
741            }
742        }
743    }
744    /// Queues GOAWAY and attempts a nonblocking flush.
745    /// Continue polling or serving to drain accepted requests and pending output.
746    /// # Errors
747    /// Returns HTTP/2 submission or transport failures.
748    pub fn shutdown_with_goaway(&mut self, error_code: u32) -> Result<(), Status> {
749        let mut inner = self.inner.borrow_mut();
750        inner.session.submit_goaway(error_code)?;
751        inner.draining = true;
752        inner.transport.set_nonblocking(true).map_err(io_status)?;
753        inner.flush()?;
754        Ok(())
755    }
756}