Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide broadcast::Sender::new and watch::Sender::new functions #4958

Open
JanBeh opened this issue Aug 30, 2022 · 4 comments · Fixed by #5824
Open

Provide broadcast::Sender::new and watch::Sender::new functions #4958

JanBeh opened this issue Aug 30, 2022 · 4 comments · Fixed by #5824
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request. M-sync Module: tokio/sync

Comments

@JanBeh
Copy link
Contributor

JanBeh commented Aug 30, 2022

Is your feature request related to a problem?

I'm planning to create an SDR framework where data is streamed between certain "processing blocks". These blocks can be dynamically connected with each other (and disconnected). I planned to use broadcast "channels" for that purpose. However, when I create a producer, I might not have a consumer (yet), so I would only need a broadcast::Sender. There is currently no way to create a Sender without also creating a Receiver.

A similar situation applies to tokio::sync::watch, where it's also not possible to create a Sender without a Receiver.

Describe the solution you'd like

I propose to add the following associated functions

  • tokio::sync::broadcast::Sender<T>::new(capacity: usize)
  • tokio::sync::watch::Sender<T>::new(init: T)

which act like

  • tokio::sync::broadcast::channel::<T>(capacity).0
  • tokio::sync::watch::channel::<T>(init).0

with the difference that the receiver isn't needlessly created and then dropped.

Describe alternatives you've considered

Using .0 on the (Sender, Receiver) pair is a good workaround, but might have unnecessary runtime overhead and is also less readable/verbose. Compare:

let x = broadcast::Sender::<T>::new(16);

vs

let x = broadcast::channel::<T>(16).0;

Additional context

Also note #4957.

@JanBeh JanBeh added A-tokio Area: The main tokio crate C-feature-request Category: A feature request. labels Aug 30, 2022
@JanBeh
Copy link
Contributor Author

JanBeh commented Aug 30, 2022

Apparently Senders without Receivers show some (maybe) surprising behavior:

use tokio::sync::watch;

#[allow(unused_variables)]
fn main() {
    let (sender, receiver) = watch::channel("initial");
    //drop(receiver); // try to uncomment
    sender.send("updated").ok();
    let receiver2 = sender.subscribe();
    let s = *receiver2.borrow();
    assert_eq!(s, "updated"); // fails if `receiver` is dropped before `send`
}

See also this post on URLO.

The other send methods (send_if_modified, send_modify, or send_replace) don't exhibit this behavior, so the proposed feature is still useful.

@marcospb19
Copy link
Contributor

I was also surprised by this, you can call broadcast::channel::<T>(CAPACITY).0 and send messages with the sender, they'll return an error, but you can just ignore them.

That's ok for broadcasts where you lose all messages previous to subscribing, implementing something else would be hard considering how it currently works.

Regarding watch, I think that's odd, it should be possible to set a value before there are listeners and get it later with watch::Receiver::borrow.

@Darksonn Darksonn added the M-sync Module: tokio/sync label Jun 27, 2023
@Darksonn
Copy link
Contributor

You can actually send a value without any receivers on a watch channel if you use send_modify.

The send method cannot be changed to allow this for backwards compatibility reasons.

@Darksonn
Copy link
Contributor

Reopening since this also applies to the watch channel.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request. M-sync Module: tokio/sync
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants