#Bounded channel that keeps the most recent message

20 messages · Page 1 of 1 (latest)

unborn breach
#

What is the mpsc channel equivalent where past messages are kicked out when the bound is hit and only the most recently sent message is sent to the receiver? mpsc sends all the messages but I just want a bounded channel that sends holds one message and sends it over when requested. it should discard the previous messages when a new one is sent.

Something like this:

let (sender, receiver) = channel(1);

sender.send("One").unwrap();
sender.send("Two").unwrap();

let message = receiver.recv().unwrap();
println!("{message}"); // Output: "Two"
supple lichen
#

The watch channel type from tokio is kind of like that (although async)

unborn breach
#

i really don't want to pull in tokio just for that

supple lichen
#

I'm not aware of one

#

you could hack this sort of thing together with a channel used as a notifier and something like a Mutex<Option<T>>

unborn breach
#

i'm just trying to get the last file changed event from notify crate sent to my channel

#

not sure how to use mutex for this

supple lichen
#

the idea would be to send nothing actually over the channel, and instead use the channel just to tell the receiving side something happened

#

then the receiving side goes and locks the mutex and takes out the value (if any)

#

if two sends happened before a receive, the receiver would read the latest value

unborn breach
#

makes sense

#

sounds incredibly hacky but this should do

#

wait no

#

i don't need the value

#

i just want the notification to be sent once

raw stream
summer notch
#

another option would be to use an mpmc channel (like crossbeam's channels), give a receiver to the same thread that has a sender, try sending a message using try_send, and if you get TrySendError::Full, use the receiver to receive and discard the oldest message to free up space and then retry sending the new message

#

something like

let mut message = Some(message);
loop {
    match sender.try_send(message.take().unwrap()) {
        Ok(_) => break,
        Err(TrySendError::Full(m)) => {
            receiver.try_recv().ok();
            message = Some(m);
        }
        Err(_) => // handle channel disconnection
    }
}