combine timeout as error with RecvError ?
keepsimple1 opened this issue · 1 comments
I'm not sure if can post this as an issue, but here it goes:
I'm trying to use Receiver::recv()
together with a timeout, similar like this example.
However, as Receiver::recv()
returns RecvError
, not std::io::Error
, things got complicated. I ended up to use anyhow::Error
but it really feels clumsy. (see code below).
Does RecvError
itself support converting from std::io::ErrorKind
? or, is there a plan to support users to create RecvError
for timeouts?
Here is my function complicated by error handling:
async fn chan_recv_with_timeout(chan: &Receiver<Vec<u8>>, timeout: Option<Duration>) -> anyhow::Result<Vec<u8>> {
let chan_f = chan.recv();
if let Some(duration) = timeout {
let time_f = Timer::after(duration);
futures::pin_mut!(chan_f);
match future::select(chan_f, time_f).await {
Either::Left((c, _)) => match c {
Ok(t) => Ok(t),
Err(r) => Err(anyhow::Error::new(r)),
},
Either::Right(_) => Err(anyhow::Error::new::<io::Error>(io::ErrorKind::TimedOut.into())),
}
} else {
match chan_f.await {
Ok(t) => Ok(t),
Err(r) => Err(anyhow::Error::new(r)),
}
}
}
You could reuse my timeout()
function and do:
timeout(duration, async { io::Result::Ok(chan.recv().await.ok()) }).await;
This way the result is io::Result<Option<Vec<u8>>
, where Ok(None)
means the channel is closed and empty.
Or, alternatively:
timeout(duration, async {
match chan.recv().await {
Ok(v) => v,
Err(err) => io::Error::new(io::ErrorKind::Other, err),
}
})
.await;
The return type is io::Result<Vec<u8>>
, and Err(_)
will represent both timeouts and channel being closed and empty.