Add std::sync::mpsc::Receiver::recv_deadline()
Essentially renames recv_max_until to recv_deadline (mostly copying recv_timeout
documentation). This function is useful to avoid the often unnecessary call to
Instant::now in recv_timeout (e.g. when the user already has a deadline). A
concrete example would be something along those lines:
```rust
use std::sync::mpsc::Receiver;
use std::time::{Duration, Instant};
/// Reads a batch of elements
///
/// Returns as soon as `max_size` elements have been received or `timeout` expires.
fn recv_batch_timeout<T>(receiver: &Receiver<T>, timeout: Duration, max_size: usize) -> Vec<T> {
recv_batch_deadline(receiver, Instant::now() + timeout, max_size)
}
/// Reads a batch of elements
///
/// Returns as soon as `max_size` elements have been received or `deadline` is reached.
fn recv_batch_deadline<T>(receiver: &Receiver<T>, deadline: Instant, max_size: usize) -> Vec<T> {
let mut result = Vec::new();
while let Ok(x) = receiver.recv_deadline(deadline) {
result.push(x);
if result.len() == max_size {
break;
}
}
result
}
```
This commit is contained in:
parent
24bb4d1e75
commit
428c875ac3
1 changed files with 61 additions and 2 deletions
|
|
@ -1297,11 +1297,70 @@ impl<T> Receiver<T> {
|
|||
Err(TryRecvError::Disconnected)
|
||||
=> Err(RecvTimeoutError::Disconnected),
|
||||
Err(TryRecvError::Empty)
|
||||
=> self.recv_max_until(Instant::now() + timeout)
|
||||
=> self.recv_deadline(Instant::now() + timeout)
|
||||
}
|
||||
}
|
||||
|
||||
fn recv_max_until(&self, deadline: Instant) -> Result<T, RecvTimeoutError> {
|
||||
/// Attempts to wait for a value on this receiver, returning an error if the
|
||||
/// corresponding channel has hung up, or if `deadline` is reached.
|
||||
///
|
||||
/// This function will always block the current thread if there is no data
|
||||
/// available and it's possible for more data to be sent. Once a message is
|
||||
/// sent to the corresponding [`Sender`][] (or [`SyncSender`]), then this
|
||||
/// receiver will wake up and return that message.
|
||||
///
|
||||
/// If the corresponding [`Sender`] has disconnected, or it disconnects while
|
||||
/// this call is blocking, this call will wake up and return [`Err`] to
|
||||
/// indicate that no more messages can ever be received on this channel.
|
||||
/// However, since channels are buffered, messages sent before the disconnect
|
||||
/// will still be properly received.
|
||||
///
|
||||
/// [`Sender`]: struct.Sender.html
|
||||
/// [`SyncSender`]: struct.SyncSender.html
|
||||
/// [`Err`]: ../../../std/result/enum.Result.html#variant.Err
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Successfully receiving value before reaching deadline:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::thread;
|
||||
/// use std::time::{Duration, Instant};
|
||||
/// use std::sync::mpsc;
|
||||
///
|
||||
/// let (send, recv) = mpsc::channel();
|
||||
///
|
||||
/// thread::spawn(move || {
|
||||
/// send.send('a').unwrap();
|
||||
/// });
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// recv.recv_deadline(Instant::now() + Duration::from_millis(400)),
|
||||
/// Ok('a')
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// Receiving an error upon reaching deadline:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::thread;
|
||||
/// use std::time::{Duration, Instant};
|
||||
/// use std::sync::mpsc;
|
||||
///
|
||||
/// let (send, recv) = mpsc::channel();
|
||||
///
|
||||
/// thread::spawn(move || {
|
||||
/// thread::sleep(Duration::from_millis(800));
|
||||
/// send.send('a').unwrap();
|
||||
/// });
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// recv.recv_deadline(Instant::now() + Duration::from_millis(400)),
|
||||
/// Err(mpsc::RecvTimeoutError::Timeout)
|
||||
/// );
|
||||
/// ```
|
||||
#[stable(feature = "mpsc_recv_deadline", since = "1.23.0")]
|
||||
pub fn recv_deadline(&self, deadline: Instant) -> Result<T, RecvTimeoutError> {
|
||||
use self::RecvTimeoutError::*;
|
||||
|
||||
loop {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue