crossbeam icon indicating copy to clipboard operation
crossbeam copied to clipboard

Channel API to select values

Open Thomasdezeeuw opened this issue 5 years ago • 3 comments
trafficstars

I'm looking for API that can remove any value from the channel based on user select. In other words I need a channel that is FIFO, but allows any value to removed if needed. For example I would like to be able to handle values with a higher priority before regular values.

For this purpose I though of the following design. It loops over all values currently in the channel allowing the user to select the value to receive next, e.g. the one with the highest priority. The user returns some type that indicates what message to remove, using that type the message is removed and returned to the user.

impl<T> Recevier<T> {
    /// Attempt to select a message to remove from the channel.
    pub fn try_select<S>(&mut self, mut selector: S) -> Option<T>
    where
        S: ValueSelector<T>,
    {
        selector.select(Values { recv: self })
            .map(|selection| { /* remove and return selection. */ })
    }
}

pub trait ValueSelector<M> {
    /// Select what value to receive.
    ///
    /// User looks over all values in `Values` and returns a `ValueSelection`, that
    /// message is removed from the channel.
    fn select<'m>(&mut self, values: Values<'m, M>) -> Option<ValueSelection>;
}

/// Iterates over all values currently in the channel.
#[derive(Debug)]
pub struct Values<'r, M> {
    recv: &'r mut Receiver<M>,
}

impl<'r, T> Iterator for Values<'m, T> {
    type Item = (MessageSelection, &'r T);

    fn next(&mut self) -> Option<Self::Item> {
        // Loop over all values in the channel, by reference.
    }
}

/// The type used to indicate what message to select.
#[derive(Copy, Clone, Debug)]
pub struct MessageSelection(/* usize ? */);

Thomasdezeeuw avatar Feb 09 '20 17:02 Thomasdezeeuw

@stjepang do you have any feedback whether or not something like this would be consider acceptable for crossbeam's channel?

Thomasdezeeuw avatar Mar 05 '20 11:03 Thomasdezeeuw

@Thomasdezeeuw It might be best to try prototyping this in a new crate first. Does the implementation support it? And what happens to other channel send/receive operations while a caller is examining the values in a channel? It seems inherent racy to me.

BurntSushi avatar Mar 05 '20 12:03 BurntSushi

@BurntSushi I was initially looking for some feedback on whether this would be considered this crate, but I'll work on it in another crate first. I don't think the send operations will be a problem, but I might have forgotten that there can be multiple receivers, that could be a problem indeed.

Thomasdezeeuw avatar Mar 06 '20 11:03 Thomasdezeeuw