flume icon indicating copy to clipboard operation
flume copied to clipboard

Consider implementing a way to try_send without consuming the message

Open let4be opened this issue 3 years ago • 4 comments

I find myself in a situation where I want to try to send a message in a channel and if buffer is full I want to send it to another "overflow" channel Right now it's impossible to do without wasteful cloning because try_send consumes the message

This can be done either by returning original message in Result's Err when there was an error or by implementing a similar Permit API as in tokio::sync::mpsc see https://docs.rs/tokio/1.0.1/tokio/sync/mpsc/struct.Permit.html

I'm personally in favor of Permit API as if done right it would allow to do other things, like getting a bunch of Permits(or one bigger Permit, depending on how we implement it) and sending a bunch of messages in one go without waiting It could probably make sending multiple messages in one go more efficient

On the other hand I could wrap the message into Arc this would solve wastefulness of the cloning I do But the Permit API, similar to tokio's could be useful for other things I described

let4be avatar Jun 09 '21 10:06 let4be

This is already supported!

https://docs.rs/flume/0.10.5/flume/struct.Sender.html#method.try_send

The function returns a Result, with TrySendError<T> as the Err variant, allowing you to get back the value. For example:

match tx.try_send(foo) {
    Ok(()) => /* Successfully sent */,
    Err(TrySendError::Full(foo)) | Err(TrySendError::Disconnected(foo)) => /* Failed to send */,
}

I could probably make this easier with an fn into_inner(self) -> T on TrySendError though. I'll add this to the next release!

zesterer avatar Jun 10 '21 14:06 zesterer

Um... This is great news!

What do you think about Permit API? Sometimes I find myself in a situation where I need to write en-bulk and all items are already there(no need to wait for), could such use case be made faster with Permits?

let4be avatar Jun 10 '21 14:06 let4be

Thinking about this carefully, I think this would be possible to implement: but not without adding some overhead to the crate. I might be able to hide it behind a non-default feature to ensure that most crate users don't need to pay the overhead, however.

That said, I'm not sure how this would interact with the async feature: the implementation could end up getting quite complex.

For this reason, I'm reluctant to do this at the current time. I'm actually working on a complete implementation overhaul of the crate that might make implementing this significantly easier, however. If I end up implementing this, I'll let you know.

zesterer avatar Jun 10 '21 15:06 zesterer

As a point of interest, the into_inner method was added in c13d0a4bb8a63dfce0254add6c1801a28960399a and is now in version 0.10.6.

zesterer avatar Jun 10 '21 15:06 zesterer