async_helpers/
responding_channel.rs1use anyhow::Error;
23use futures::SinkExt;
24use futures::channel::{mpsc, oneshot};
25use futures::stream::{FusedStream, Stream};
26use std::pin::Pin;
27use std::task::{Context, Poll};
28
29pub struct Sender<Req, Resp> {
31 inner: mpsc::Sender<(Req, Responder<Resp>)>,
32}
33
34impl<Req, Resp> Clone for Sender<Req, Resp> {
35 fn clone(&self) -> Self {
36 Self { inner: self.inner.clone() }
37 }
38}
39
40impl<Req, Resp> Sender<Req, Resp> {
41 pub async fn request(&mut self, value: Req) -> Result<Resp, Error> {
46 let (responder, response) = oneshot::channel();
47 self.inner.send((value, Responder { inner: responder })).await?;
48 Ok(response.await?)
49 }
50}
51
52pub struct Responder<Resp> {
54 inner: oneshot::Sender<Resp>,
55}
56
57impl<Resp> Responder<Resp> {
58 pub fn respond(self, value: Resp) -> Result<(), Resp> {
62 self.inner.send(value)
63 }
64}
65
66pub struct Receiver<Req, Resp> {
71 inner: mpsc::Receiver<(Req, Responder<Resp>)>,
72}
73
74impl<Req, Resp> Receiver<Req, Resp> {
75 pub fn close(&mut self) {
80 self.inner.close();
81 }
82
83 pub fn try_receive(&mut self) -> Result<Option<(Req, Responder<Resp>)>, Error> {
88 match self.inner.try_recv() {
89 Ok(msg) => Ok(Some(msg)),
90 Err(mpsc::TryRecvError::Closed) => Ok(None),
91 Err(e @ mpsc::TryRecvError::Empty) => Err(e.into()),
92 }
93 }
94}
95
96impl<Req, Resp> Stream for Receiver<Req, Resp> {
97 type Item = (Req, Responder<Resp>);
98
99 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
100 Pin::new(&mut self.inner).poll_next(cx)
101 }
102}
103
104impl<Req, Resp> FusedStream for Receiver<Req, Resp> {
105 fn is_terminated(&self) -> bool {
106 self.inner.is_terminated()
107 }
108}
109
110pub fn channel<Req, Resp>(buffer: usize) -> (Sender<Req, Resp>, Receiver<Req, Resp>) {
115 let (inner_sender, inner_receiver) = mpsc::channel(buffer);
116 (Sender { inner: inner_sender }, Receiver { inner: inner_receiver })
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122 use fuchsia_async as fasync;
123 use futures::StreamExt;
124 use std::pin::pin;
125
126 macro_rules! unwrap_ready {
127 ($poll:expr) => {
128 match $poll {
129 Poll::Ready(value) => value,
130 Poll::Pending => panic!("not ready"),
131 }
132 };
133 }
134
135 #[test]
136 fn sender_receives_response() {
137 let mut ex = fasync::TestExecutor::new();
138 let (mut sender, mut receiver) = channel(0);
139
140 let received = receiver.next();
141 let mut received = pin!(received);
142 assert!(ex.run_until_stalled(&mut received).is_pending());
143
144 let request = sender.request(());
145 let mut request = pin!(request);
146 assert!(ex.run_until_stalled(&mut request).is_pending());
147
148 let ((), responder) = unwrap_ready!(ex.run_until_stalled(&mut received)).unwrap();
149
150 assert!(ex.run_until_stalled(&mut request).is_pending());
151
152 responder.respond(()).unwrap();
153
154 unwrap_ready!(ex.run_until_stalled(&mut request)).unwrap();
155 }
156
157 #[test]
158 fn cloned_senders_go_to_same_receiver() {
159 let mut ex = fasync::TestExecutor::new();
160 let (mut sender, mut receiver) = channel(0);
161 let mut sender2 = sender.clone();
162
163 let received = receiver.next();
164 let mut received = pin!(received);
165 assert!(ex.run_until_stalled(&mut received).is_pending());
166
167 let request = sender.request(());
168 let mut request = pin!(request);
169 assert!(ex.run_until_stalled(&mut request).is_pending());
170
171 let ((), responder) = unwrap_ready!(ex.run_until_stalled(&mut received)).unwrap();
172
173 assert!(ex.run_until_stalled(&mut request).is_pending());
174
175 responder.respond(()).unwrap();
176
177 unwrap_ready!(ex.run_until_stalled(&mut request)).unwrap();
178
179 let received = receiver.next();
180 let mut received = pin!(received);
181 assert!(ex.run_until_stalled(&mut received).is_pending());
182
183 let request = sender2.request(());
184 let mut request = pin!(request);
185 assert!(ex.run_until_stalled(&mut request).is_pending());
186
187 let ((), responder) = unwrap_ready!(ex.run_until_stalled(&mut received)).unwrap();
188
189 assert!(ex.run_until_stalled(&mut request).is_pending());
190
191 responder.respond(()).unwrap();
192
193 unwrap_ready!(ex.run_until_stalled(&mut request)).unwrap();
194 }
195
196 #[test]
197 fn sender_receives_error_on_dropped_receiver() {
198 let mut ex = fasync::TestExecutor::new();
199 let (mut sender, receiver) = channel::<(), ()>(0);
200
201 let request = sender.request(());
202 let mut request = pin!(request);
203 assert!(ex.run_until_stalled(&mut request).is_pending());
204
205 drop(receiver);
206
207 assert!(unwrap_ready!(ex.run_until_stalled(&mut request)).is_err());
208 }
209
210 #[test]
211 fn sender_receives_error_on_dropped_responder() {
212 let mut ex = fasync::TestExecutor::new();
213 let (mut sender, mut receiver) = channel::<(), ()>(0);
214
215 let request = sender.request(());
216 let mut request = pin!(request);
217 assert!(ex.run_until_stalled(&mut request).is_pending());
218
219 let received = receiver.next();
220 let mut received = pin!(received);
221 let ((), responder) = unwrap_ready!(ex.run_until_stalled(&mut received)).unwrap();
222
223 assert!(ex.run_until_stalled(&mut request).is_pending());
224 drop(responder);
225
226 assert!(unwrap_ready!(ex.run_until_stalled(&mut request)).is_err());
227 }
228
229 #[test]
230 fn receiver_receives_error_on_dropped_sender() {
231 let mut ex = fasync::TestExecutor::new();
232 let (sender, mut receiver) = channel::<(), ()>(0);
233
234 let received = receiver.next();
235 let mut received = pin!(received);
236 assert!(ex.run_until_stalled(&mut received).is_pending());
237
238 drop(sender);
239
240 assert!(unwrap_ready!(ex.run_until_stalled(&mut received)).is_none());
241 }
242
243 #[test]
244 fn responder_returns_error_on_dropped_sender() {
245 let mut ex = fasync::TestExecutor::new();
246 let (mut sender, mut receiver) = channel(0);
247
248 {
249 let request = sender.request(());
250 let mut request = pin!(request);
251 assert!(ex.run_until_stalled(&mut request).is_pending());
252 } let received = receiver.next();
255 let mut received = pin!(received);
256 let ((), responder) = unwrap_ready!(ex.run_until_stalled(&mut received)).unwrap();
257
258 drop(sender);
259
260 assert!(responder.respond(()).is_err());
261 }
262
263 #[fuchsia::test(allow_stalls = false)]
264 async fn cannot_request_after_receiver_closed() {
265 let (mut sender, mut receiver) = channel::<(), ()>(0);
266 receiver.close();
267 assert!(sender.request(()).await.is_err());
268 }
269
270 #[test]
271 fn try_receive_returns_none_when_channel_is_empty() {
272 let (_, mut receiver) = channel::<(), ()>(0);
273 assert!(receiver.try_receive().unwrap().is_none());
274 }
275
276 #[test]
277 fn try_receive_returns_none_after_none_result() {
278 let (_, mut receiver) = channel::<(), ()>(0);
279 assert!(receiver.try_receive().unwrap().is_none());
280 assert!(receiver.try_receive().unwrap().is_none());
281 }
282
283 #[test]
284 fn try_receive_returns_value_when_channel_has_value() {
285 let mut ex = fasync::TestExecutor::new();
286 let (mut sender, mut receiver) = channel::<(), ()>(0);
287
288 let request = sender.request(());
289 let mut request = pin!(request);
290 assert!(ex.run_until_stalled(&mut request).is_pending());
291
292 assert!(receiver.try_receive().unwrap().is_some());
293 }
294}