tokio-rs / tokio

A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...
https://tokio.rs
MIT License
26.94k stars 2.48k forks source link

Feature request: Allow non-Send broadcast values in more (generic) contexts #6902

Open jplatte opened 3 weeks ago

jplatte commented 3 weeks ago

Is your feature request related to a problem? Please describe.

In my library eyeball-im, I use tokio_util::sync::ReusableBoxFuture to implement a Stream on top of a tokio::sync::broadcast channel. This is the same thing tokio_stream::wrappers::BroadcastStream does. However, this means that the messages being sent over the channel must be Send. I can also box the future myself without requiring Sendness of the message type, but then my own receive futures become non-Send.

Describe the solution you'd like

I would like to avoid boxing to let the compiler infer Send-ness of the involves futures. If tokio::sync::broadcast::Receiver::recv returned a named future, tokio_stream::wrappers::BroadcastStream could drop the Send bound on T, and I could drop the same bound in my library too.

Describe alternatives you've considered

I have a PR with a copy-pasted ReusableBoxFuture without the Send bounds, and a wrapper type for it that is only ever instantiated with the same (unnameable) future that invokes receiver.recv() and that I know is Send if the message type is. There's a static assertion that T: Send -> <unnameable future>: Send, and unsafely implemented Send for the wrapper type: https://github.com/jplatte/eyeball/pull/63/commits/e4fd1f59bf4bf283e0c8d413e73316169ef20d9f#diff-5a8e4292bd84885e0f16976040ee79e231ab74df5283d52565cd4fec4ab92d75R271-R292

However, it seems wrong to require unsafe for this. My code's soundness is probably relying on tokio not doing weird things with the Send-ness of the broadcast::Receiver::recv future.. not a huge deal but it doesn't feel good to release unsafe code with no serious attempt at a soundness proof.

jplatte commented 2 weeks ago

@Darksonn I see you added some labels. Is this feature request is "accepted" then, i.e. a PR for this would be welcome?

Darksonn commented 2 weeks ago

I don't know if adding labels necessarily means that, but yes I would be okay with a PR for this. Sorry for not responding earlier. I think we can perhaps add an unsafe method to ReusableBoxFuture that takes a Future without a 'static or Send bound, and then it's up to the caller to make sure that they don't use the future in violation of its true trait bounds.

jplatte commented 2 weeks ago

I don't know if adding labels necessarily means that

Yeah I don't think it does, but it means you looked at and understood the request, so I felt like nothing more was going to happen until I explicitly asked :)