1use std::{cell::RefCell, rc::Rc};
5
6use grpc_core::{Metadata, Status};
7#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
9pub enum StreamError {
10 #[error("stream would block")]
12 WouldBlock,
13 #[error("{0}")]
15 Status(#[from] Status),
16}
17type Result<T> = std::result::Result<T, StreamError>;
18fn invalid(message: &str) -> StreamError {
19 Status::failed_precondition(message).into()
20}
21pub trait StreamDriver {
34 type Send;
35 type Receive;
36 fn send(&mut self, message: &Self::Send) -> Result<()>;
40 fn half_close(&mut self) -> Result<()>;
44 fn try_recv_next(&mut self) -> Result<Option<Self::Receive>>;
48 fn wait_ready(&mut self) -> Result<()>;
52 fn finish(&mut self, status: &Status, trailers: &Metadata) -> Result<()>;
56 fn initial_metadata(&self) -> Option<&Metadata>;
57 fn trailing_metadata(&self) -> Option<&Metadata>;
58 fn cancel(&mut self);
59}
60struct State<D: StreamDriver> {
61 driver: D,
62 error: Option<StreamError>,
63 receive_closed: bool,
64 send_closed: bool,
65 complete: bool,
66 client: bool,
67}
68impl<D: StreamDriver> State<D> {
69 fn fail(&mut self, error: StreamError) -> StreamError {
70 self.error = Some(error.clone());
71 if !self.complete {
72 self.driver.cancel();
73 }
74 self.complete = true;
75 error
76 }
77 fn check(&self) -> Result<()> {
78 self.error.clone().map_or(Ok(()), Err)
79 }
80 fn accept<T>(&mut self, result: Result<T>) -> Result<T> {
81 match result {
82 Err(StreamError::WouldBlock) => Err(StreamError::WouldBlock),
83 Err(e) => Err(self.fail(e)),
84 Ok(value) => Ok(value),
85 }
86 }
87 fn poll(&mut self) -> Result<Option<D::Receive>> {
88 self.check()?;
89 if self.receive_closed {
90 return Ok(None);
91 }
92 let result = self.driver.try_recv_next();
93 let message = self.accept(result)?;
94 if message.is_none() {
95 if self.client && self.driver.trailing_metadata().is_none() {
96 return Err(
97 self.fail(Status::unknown("response ended without validated trailers").into())
98 );
99 }
100 self.receive_closed = true;
101 if self.client {
102 if !self.send_closed {
103 self.driver.cancel();
104 }
105 (self.complete, self.send_closed) = (true, true);
106 }
107 }
108 Ok(message)
109 }
110 fn send(&mut self, value: &D::Send) -> Result<()> {
111 self.check()?;
112 if self.send_closed {
113 return Err(invalid("send direction is closed"));
114 }
115 let result = self.driver.send(value);
116 self.accept(result)
117 }
118 fn close(&mut self) -> Result<()> {
119 self.check()?;
120 if self.send_closed {
121 return Ok(());
122 }
123 let result = self.driver.half_close();
124 self.accept(result)?;
125 self.send_closed = true;
126 Ok(())
127 }
128 fn finish(&mut self, status: &Status, trailers: &Metadata) -> Result<()> {
129 self.check()?;
130 if self.complete {
131 return Err(invalid("RPC is already finished"));
132 }
133 let result = self.driver.finish(status, trailers);
134 self.accept(result)?;
135 (self.complete, self.send_closed, self.receive_closed) = (true, true, true);
136 Ok(())
137 }
138 fn wait(&mut self) -> Result<()> {
139 self.check()?;
140 match self.driver.wait_ready() {
141 Ok(()) => Ok(()),
142 Err(StreamError::WouldBlock) => {
143 Err(self.fail(Status::internal("driver wait made no progress").into()))
144 }
145 Err(e) => Err(self.fail(e)),
146 }
147 }
148 fn cancel(&mut self) {
149 if !self.complete {
150 self.fail(Status::cancelled("call cancelled").into());
151 }
152 }
153}
154impl<D: StreamDriver> Drop for State<D> {
155 fn drop(&mut self) {
156 if !self.complete {
157 self.driver.cancel();
158 }
159 }
160}
161trait Control {
162 fn fail(&mut self, error: StreamError) -> Result<()>;
163 fn wait(&mut self) -> Result<()>;
164 fn metadata(&self, trailing: bool) -> Result<Option<Metadata>>;
165 fn cancel(&mut self) -> Result<()>;
166}
167trait Receive<T>: Control {
168 fn poll(&mut self) -> Result<Option<T>>;
169}
170trait Send<T>: Control {
171 fn send(&mut self, value: &T) -> Result<()>;
172 fn close(&mut self) -> Result<()>;
173 fn finish(&mut self, status: &Status, trailers: &Metadata) -> Result<()>;
174}
175struct Handle<D: StreamDriver>(Rc<RefCell<State<D>>>);
176impl<D: StreamDriver> Handle<D> {
177 fn with<T>(&self, f: impl FnOnce(&mut State<D>) -> Result<T>) -> Result<T> {
178 let mut state = self
179 .0
180 .try_borrow_mut()
181 .map_err(|_| invalid("reentrant stream operation"))?;
182 f(&mut state)
183 }
184}
185impl<D: StreamDriver> Control for Handle<D> {
186 fn fail(&mut self, error: StreamError) -> Result<()> {
187 self.with(|state| {
188 state.fail(error);
189 Ok(())
190 })
191 }
192 fn wait(&mut self) -> Result<()> {
193 self.with(State::wait)
194 }
195 fn metadata(&self, trailing: bool) -> Result<Option<Metadata>> {
196 let state = self
197 .0
198 .try_borrow()
199 .map_err(|_| invalid("reentrant metadata access"))?;
200 Ok(if trailing {
201 state.driver.trailing_metadata()
202 } else {
203 state.driver.initial_metadata()
204 }
205 .cloned())
206 }
207 fn cancel(&mut self) -> Result<()> {
208 self.with(|state| {
209 state.cancel();
210 Ok(())
211 })
212 }
213}
214impl<D: StreamDriver> Receive<D::Receive> for Handle<D> {
215 fn poll(&mut self) -> Result<Option<D::Receive>> {
216 self.with(State::poll)
217 }
218}
219impl<D: StreamDriver> Send<D::Send> for Handle<D> {
220 fn send(&mut self, value: &D::Send) -> Result<()> {
221 self.with(|s| s.send(value))
222 }
223 fn close(&mut self) -> Result<()> {
224 self.with(State::close)
225 }
226 fn finish(&mut self, status: &Status, trailers: &Metadata) -> Result<()> {
227 self.with(|s| s.finish(status, trailers))
228 }
229}
230type Shared<D> = Rc<RefCell<State<D>>>;
231fn shared<D: StreamDriver>(driver: D, client: bool, send_closed: bool) -> Shared<D> {
232 Rc::new(RefCell::new(State {
233 driver,
234 error: None,
235 receive_closed: false,
236 send_closed,
237 complete: false,
238 client,
239 }))
240}
241fn blocking<T, C: Control + ?Sized>(
242 control: &mut C,
243 mut step: impl FnMut(&mut C) -> Result<T>,
244) -> Result<T> {
245 loop {
246 match step(control) {
247 Err(StreamError::WouldBlock) => control.wait()?,
248 result => return result,
249 }
250 }
251}
252macro_rules! control_methods {
253 ($($field:ident).+) => {
254 pub fn initial_metadata(&self) -> Result<Option<Metadata>> {
258 self.$($field).+.metadata(false)
259 }
260 pub fn trailing_metadata(&self) -> Result<Option<Metadata>> {
264 self.$($field).+.metadata(true)
265 }
266 pub fn cancel(&mut self) -> Result<()> { self.$($field).+.cancel() }
270 };
271}
272macro_rules! send_methods {
273 ($message:ty, $($field:ident).+) => {
274 pub fn send(&mut self, value: &$message) -> Result<()> {
278 blocking(self.$($field).+.as_mut(), |sender| sender.send(value))
279 }
280 pub fn try_send(&mut self, value: &$message) -> Result<()> { self.$($field).+.send(value) }
284 };
285}
286macro_rules! close_methods {
287 ($($field:ident).+) => {
288 pub fn half_close(&mut self) -> Result<()> {
292 blocking(self.$($field).+.as_mut(), |sender| sender.close())
293 }
294 pub fn try_half_close(&mut self) -> Result<()> { self.$($field).+.close() }
298 };
299}
300pub struct ServerStreamingCall<T> {
302 receiver: Box<dyn Receive<T>>,
303}
304impl<T: 'static> ServerStreamingCall<T> {
305 pub fn new<D: StreamDriver<Receive = T> + 'static>(driver: D) -> Self {
307 Self {
308 receiver: Box::new(Handle(shared(driver, true, true))),
309 }
310 }
311 pub fn try_recv_next(&mut self) -> Result<Option<T>> {
315 self.receiver.poll()
316 }
317 pub fn recv_next(&mut self) -> Result<Option<T>> {
321 blocking(self.receiver.as_mut(), |receiver| receiver.poll())
322 }
323 pub fn finish(&mut self) -> Result<Vec<T>> {
327 let mut messages = Vec::new();
328 while let Some(message) = self.recv_next()? {
329 messages.push(message);
330 }
331 Ok(messages)
332 }
333 control_methods!(receiver);
334}
335pub struct RequestStream<Req>(ServerStreamingCall<Req>);
338impl<Req: 'static> RequestStream<Req> {
339 pub fn new<D: StreamDriver<Receive = Req> + 'static>(driver: D) -> Self {
341 Self(ServerStreamingCall {
342 receiver: Box::new(Handle(shared(driver, false, false))),
343 })
344 }
345}
346impl<Req> std::ops::Deref for RequestStream<Req> {
347 type Target = ServerStreamingCall<Req>;
348 fn deref(&self) -> &Self::Target {
349 &self.0
350 }
351}
352impl<Req> std::ops::DerefMut for RequestStream<Req> {
353 fn deref_mut(&mut self) -> &mut Self::Target {
354 &mut self.0
355 }
356}
357pub struct ResponseSink<T> {
359 sender: Box<dyn Send<T>>,
360}
361impl<T> ResponseSink<T> {
362 send_methods!(T, sender);
363 pub fn try_finish(&mut self, status: &Status, trailers: &Metadata) -> Result<()> {
367 self.sender.finish(status, trailers)
368 }
369 pub fn finish(&mut self, status: Status, trailers: Metadata) -> Result<()> {
373 blocking(self.sender.as_mut(), |sender| {
374 sender.finish(&status, &trailers)
375 })
376 }
377 control_methods!(sender);
378}
379pub fn server_streams<D: StreamDriver + 'static>(
381 driver: D,
382) -> (RequestStream<D::Receive>, ResponseSink<D::Send>) {
383 let state = shared(driver, false, false);
384 (
385 RequestStream(ServerStreamingCall {
386 receiver: Box::new(Handle(Rc::clone(&state))),
387 }),
388 ResponseSink {
389 sender: Box::new(Handle(state)),
390 },
391 )
392}
393pub struct BidiStreamingCall<Req, Resp> {
395 incoming: ServerStreamingCall<Resp>,
396 outgoing: ResponseSink<Req>,
397}
398impl<Req: 'static, Resp: 'static> BidiStreamingCall<Req, Resp> {
399 pub fn new<D: StreamDriver<Send = Req, Receive = Resp> + 'static>(driver: D) -> Self {
400 let state = shared(driver, true, false);
401 Self {
402 incoming: ServerStreamingCall {
403 receiver: Box::new(Handle(Rc::clone(&state))),
404 },
405 outgoing: ResponseSink {
406 sender: Box::new(Handle(state)),
407 },
408 }
409 }
410 send_methods!(Req, outgoing.sender);
411 close_methods!(outgoing.sender);
412 pub fn try_recv_next(&mut self) -> Result<Option<Resp>> {
416 self.incoming.try_recv_next()
417 }
418 pub fn recv_next(&mut self) -> Result<Option<Resp>> {
422 self.incoming.recv_next()
423 }
424 pub fn finish(&mut self) -> Result<Vec<Resp>> {
428 self.half_close()?;
429 self.incoming.finish()
430 }
431 control_methods!(incoming.receiver);
432}
433pub struct ClientStreamingCall<Req, Resp> {
435 call: BidiStreamingCall<Req, Resp>,
436 response: Option<Resp>,
437 delivered: bool,
438}
439impl<Req: 'static, Resp: 'static> ClientStreamingCall<Req, Resp> {
440 pub fn new<D: StreamDriver<Send = Req, Receive = Resp> + 'static>(driver: D) -> Self {
441 Self {
442 call: BidiStreamingCall::new(driver),
443 response: None,
444 delivered: false,
445 }
446 }
447 send_methods!(Req, call.outgoing.sender);
448 close_methods!(call.outgoing.sender);
449 pub fn try_finish(&mut self) -> Result<Resp> {
453 if self.delivered {
454 return Err(invalid("response already delivered"));
455 }
456 let result = self.poll_finish();
457 if let Err(error) = &result
458 && *error != StreamError::WouldBlock
459 {
460 self.call.incoming.receiver.fail(error.clone())?;
461 }
462 result
463 }
464 fn poll_finish(&mut self) -> Result<Resp> {
465 self.call.try_half_close()?;
466 if self.response.is_none() {
467 match self.call.try_recv_next()? {
468 Some(message) => self.response = Some(message),
469 None => return Err(Status::internal("missing client-streaming response").into()),
470 }
471 }
472 match self.call.try_recv_next()? {
473 Some(_) => Err(Status::internal("multiple client-streaming responses").into()),
474 None => {
475 self.delivered = true;
476 self.response
477 .take()
478 .ok_or_else(|| Status::internal("missing client-streaming response").into())
479 }
480 }
481 }
482 pub fn try_recv_next(&mut self) -> Result<Option<Resp>> {
486 (!self.delivered).then(|| self.try_finish()).transpose()
487 }
488 pub fn recv_next(&mut self) -> Result<Option<Resp>> {
492 (!self.delivered).then(|| self.finish()).transpose()
493 }
494 pub fn finish(&mut self) -> Result<Resp> {
498 loop {
499 match self.try_finish() {
500 Err(StreamError::WouldBlock) => self.call.incoming.receiver.wait()?,
501 result => return result,
502 }
503 }
504 }
505 control_methods!(call.incoming.receiver);
506}
507#[cfg(test)]
508mod unit_lifecycle_scenario {
509 use std::collections::VecDeque;
510
511 use super::*;
512 type TestResult = std::result::Result<(), Box<dyn std::error::Error>>;
513 #[derive(Default)]
514 struct Journal {
515 ops: Vec<&'static str>,
516 accepted: Vec<i32>,
517 finished: Vec<(Status, Metadata)>,
518 }
519 struct Script {
520 incoming: VecDeque<Result<Option<i32>>>,
521 sends: VecDeque<Result<()>>,
522 closes: VecDeque<Result<()>>,
523 finishes: VecDeque<Result<()>>,
524 waits: VecDeque<Result<()>>,
525 initial: Metadata,
526 trailers: Option<Metadata>,
527 send_trailers: bool,
528 log: Rc<RefCell<Journal>>,
529 }
530 impl Script {
531 fn new(events: Vec<Result<Option<i32>>>) -> (Self, Rc<RefCell<Journal>>) {
532 let log = Rc::new(RefCell::new(Journal::default()));
533 (
534 Self {
535 incoming: events.into(),
536 sends: VecDeque::new(),
537 closes: VecDeque::new(),
538 finishes: VecDeque::new(),
539 waits: VecDeque::new(),
540 initial: Metadata::new(),
541 trailers: None,
542 send_trailers: true,
543 log: Rc::clone(&log),
544 },
545 log,
546 )
547 }
548 fn attempt(queue: &mut VecDeque<Result<()>>) -> Result<()> {
549 queue.pop_front().transpose().map(|_| ())
550 }
551 fn record(&self, operation: &'static str) {
552 self.log.borrow_mut().ops.push(operation);
553 }
554 }
555 impl StreamDriver for Script {
556 type Send = i32;
557 type Receive = i32;
558 fn send(&mut self, value: &i32) -> Result<()> {
559 self.record("send");
560 Self::attempt(&mut self.sends)?;
561 self.log.borrow_mut().accepted.push(*value);
562 Ok(())
563 }
564 fn half_close(&mut self) -> Result<()> {
565 self.record("close");
566 Self::attempt(&mut self.closes)
567 }
568 fn try_recv_next(&mut self) -> Result<Option<i32>> {
569 self.record("recv");
570 let result = self
571 .incoming
572 .pop_front()
573 .ok_or_else(|| invalid("script exhausted"))?;
574 if self.send_trailers && matches!(&result, Ok(None) | Err(StreamError::Status(_))) {
575 self.trailers = Some(Metadata::new());
576 }
577 result
578 }
579 fn wait_ready(&mut self) -> Result<()> {
580 self.record("wait");
581 Self::attempt(&mut self.waits)
582 }
583 fn finish(&mut self, status: &Status, trailers: &Metadata) -> Result<()> {
584 self.record("finish");
585 Self::attempt(&mut self.finishes)?;
586 self.log
587 .borrow_mut()
588 .finished
589 .push((status.clone(), trailers.clone()));
590 Ok(())
591 }
592 fn initial_metadata(&self) -> Option<&Metadata> {
593 Some(&self.initial)
594 }
595 fn trailing_metadata(&self) -> Option<&Metadata> {
596 self.trailers.as_ref()
597 }
598 fn cancel(&mut self) {
599 self.record("cancel");
600 }
601 }
602 #[test]
603 fn server_stream_pending_metadata_and_completion() -> TestResult {
604 let (mut driver, log) =
605 Script::new(vec![Err(StreamError::WouldBlock), Ok(Some(7)), Ok(None)]);
606 driver.initial.append_ascii("tag", "a")?;
607 driver.initial.append_ascii("tag", "b")?;
608 driver.initial.append_binary("raw-bin", &[0, 255])?;
609 let initial = driver.initial.clone();
610 let mut call = ServerStreamingCall::new(driver);
611 assert_eq!(call.try_recv_next(), Err(StreamError::WouldBlock));
612 assert_eq!(log.borrow().ops, ["recv"]);
613 assert_eq!(call.initial_metadata()?, Some(initial.clone()));
614 assert_eq!(call.trailing_metadata()?, None);
615 assert_eq!(call.recv_next()?, Some(7));
616 assert_eq!(call.recv_next()?, None);
617 assert_eq!(call.try_recv_next()?, None);
618 assert_eq!(call.initial_metadata()?, Some(initial));
619 assert_eq!(call.trailing_metadata()?, Some(Metadata::new()));
620 drop(call);
621 assert_eq!(log.borrow().ops, ["recv", "recv", "recv"]);
622 Ok(())
623 }
624 #[test]
625 fn blocking_receive_waits_and_failure_is_sticky() -> TestResult {
626 let failure = StreamError::from(Status::unavailable("offline"));
627 let (driver, log) = Script::new(vec![
628 Err(StreamError::WouldBlock),
629 Ok(Some(3)),
630 Err(failure.clone()),
631 Ok(Some(9)),
632 ]);
633 let mut call = ServerStreamingCall::new(driver);
634 assert_eq!(call.recv_next()?, Some(3));
635 assert_eq!(log.borrow().ops, ["recv", "wait", "recv"]);
636 assert_eq!(call.recv_next(), Err(failure.clone()));
637 assert_eq!(call.try_recv_next(), Err(failure));
638 assert_eq!(call.trailing_metadata()?, Some(Metadata::new()));
639 call.cancel()?;
640 drop(call);
641 assert_eq!(log.borrow().ops, ["recv", "wait", "recv", "recv", "cancel"]);
642 Ok(())
643 }
644 #[test]
645 fn client_response_waits_for_status_and_enforces_cardinality() -> TestResult {
646 let (driver, log) = Script::new(vec![Ok(Some(8)), Err(StreamError::WouldBlock), Ok(None)]);
647 let mut call = ClientStreamingCall::new(driver);
648 assert_eq!(call.try_recv_next(), Err(StreamError::WouldBlock));
649 assert_eq!(call.recv_next()?, Some(8));
650 assert_eq!(call.try_recv_next()?, None);
651 assert!(call.try_finish().is_err());
652 drop(call);
653 assert_eq!(log.borrow().ops, ["close", "recv", "recv", "recv"]);
654 for events in [
655 vec![Ok(None)],
656 vec![Ok(Some(1)), Ok(Some(2))],
657 vec![Ok(Some(1)), Err(Status::unavailable("late status").into())],
658 ] {
659 let (driver, _) = Script::new(events);
660 let mut call = ClientStreamingCall::new(driver);
661 let first = call.try_finish();
662 assert!(matches!(first, Err(StreamError::Status(_))));
663 assert_eq!(call.try_finish(), first);
664 assert_eq!(call.try_send(&9).err(), first.clone().err());
665 assert_eq!(call.try_half_close().err(), first.err());
666 }
667 Ok(())
668 }
669 #[test]
670 fn blocking_client_finish_waits_only_for_pending_io() -> TestResult {
671 let (mut driver, log) =
672 Script::new(vec![Err(StreamError::WouldBlock), Ok(Some(4)), Ok(None)]);
673 driver.closes.push_back(Err(StreamError::WouldBlock));
674 let mut call = ClientStreamingCall::new(driver);
675 call.send(&1)?;
676 assert_eq!(call.finish()?, 4);
677 assert_eq!(log.borrow().accepted, [1]);
678 assert_eq!(
679 log.borrow().ops.join(","),
680 "send,close,wait,close,recv,wait,recv,recv"
681 );
682 Ok(())
683 }
684 #[test]
685 fn bidi_backpressure_half_close_preserves_responses() -> TestResult {
686 let (mut driver, log) = Script::new(vec![Ok(Some(5)), Ok(Some(6)), Ok(None)]);
687 driver.sends = vec![Err(StreamError::WouldBlock); 2].into();
688 driver.sends.push_back(Ok(()));
689 driver.closes = vec![Err(StreamError::WouldBlock), Ok(())].into();
690 let mut call = BidiStreamingCall::new(driver);
691 assert_eq!(call.try_send(&4), Err(StreamError::WouldBlock));
692 assert!(log.borrow().accepted.is_empty());
693 assert_eq!(call.recv_next()?, Some(5));
694 call.send(&4)?;
695 assert_eq!(call.try_half_close(), Err(StreamError::WouldBlock));
696 call.half_close()?;
697 call.half_close()?;
698 assert!(call.try_send(&99).is_err());
699 assert_eq!(call.finish()?, vec![6]);
700 drop(call);
701 assert_eq!(log.borrow().accepted, [4]);
702 assert_eq!(
703 log.borrow().ops.join(","),
704 "send,recv,send,wait,send,close,close,recv,recv"
705 );
706 let (driver, log) = Script::new(vec![Ok(None)]);
707 let mut call = BidiStreamingCall::new(driver);
708 assert_eq!(call.try_recv_next()?, None);
709 drop(call);
710 assert_eq!(log.borrow().ops, ["recv", "cancel"]);
711 Ok(())
712 }
713 #[test]
714 fn server_halves_finish_and_last_drop_control_lifetime() -> TestResult {
715 let (mut driver, log) = Script::new(vec![Ok(None)]);
716 driver.finishes = vec![Err(StreamError::WouldBlock); 2].into();
717 driver.finishes.push_back(Ok(()));
718 let (mut requests, mut responses) = server_streams(driver);
719 assert_eq!(requests.try_recv_next()?, None);
720 drop(requests);
721 responses.send(&2)?;
722 let status = Status::permission_denied("denied");
723 let mut trailers = Metadata::new();
724 trailers.append_ascii("reason", "policy")?;
725 assert_eq!(
726 responses.try_finish(&status, &trailers),
727 Err(StreamError::WouldBlock)
728 );
729 responses.finish(status.clone(), trailers.clone())?;
730 assert!(responses.try_send(&3).is_err());
731 assert!(responses.finish(Status::ok(""), Metadata::new()).is_err());
732 drop(responses);
733 assert_eq!(log.borrow().finished, [(status, trailers)]);
734 assert_eq!(
735 log.borrow().ops,
736 ["recv", "send", "finish", "finish", "wait", "finish"]
737 );
738 let (driver, log) = Script::new(vec![Ok(None)]);
739 let mut requests = RequestStream::new(driver);
740 assert_eq!(requests.recv_next()?, None);
741 drop(requests);
742 assert_eq!(log.borrow().ops, ["recv", "cancel"]);
743 let (driver, log) = Script::new(vec![]);
744 let (requests, responses) = server_streams(driver);
745 drop(responses);
746 assert!(log.borrow().ops.is_empty());
747 drop(requests);
748 assert_eq!(log.borrow().ops, ["cancel"]);
749 Ok(())
750 }
751 #[test]
752 fn cancellation_and_invalid_wait_are_terminal() -> TestResult {
753 let (driver, log) = Script::new(vec![Ok(Some(1))]);
754 let mut call = BidiStreamingCall::new(driver);
755 call.half_close()?;
756 call.cancel()?;
757 call.cancel()?;
758 assert!(call.try_send(&1).is_err());
759 assert!(call.try_recv_next().is_err());
760 assert!(call.initial_metadata()?.is_some());
761 drop(call);
762 assert_eq!(log.borrow().ops, ["close", "cancel"]);
763 let (mut driver, log) = Script::new(vec![Ok(None), Ok(Some(9))]);
764 driver.send_trailers = false;
765 let mut call = ServerStreamingCall::new(driver);
766 let failure = call.recv_next();
767 assert!(
768 matches!(&failure, Err(StreamError::Status(s)) if s.code() == grpc_core::Code::Unknown)
769 );
770 assert_eq!(call.try_recv_next(), failure);
771 drop(call);
772 assert_eq!(log.borrow().ops, ["recv", "cancel"]);
773 let (mut driver, log) = Script::new(vec![Err(StreamError::WouldBlock)]);
774 driver.waits.push_back(Err(StreamError::WouldBlock));
775 let mut call = ServerStreamingCall::new(driver);
776 assert!(matches!(call.recv_next(), Err(StreamError::Status(_))));
777 drop(call);
778 assert_eq!(log.borrow().ops, ["recv", "wait", "cancel"]);
779 Ok(())
780 }
781}