tokio::sync::watch

Struct Sender

Source
pub struct Sender<T> { /* private fields */ }
Expand description

Sends values to the associated Receiver.

Instances are created by the channel function.

Implementations§

Source§

impl<T> Sender<T>

Source

pub fn new(init: T) -> Self

Creates the sending-half of the watch channel.

See documentation of watch::channel for errors when calling this function. Beware that attempting to send a value when there are no receivers will return an error.

§Examples
let sender = tokio::sync::watch::Sender::new(0u8);
assert!(sender.send(3).is_err());
let _rec = sender.subscribe();
assert!(sender.send(4).is_ok());
Source

pub fn send(&self, value: T) -> Result<(), SendError<T>>

Sends a new value via the channel, notifying all receivers.

This method fails if the channel is closed, which is the case when every receiver has been dropped. It is possible to reopen the channel using the subscribe method. However, when send fails, the value isn’t made available for future receivers (but returned with the SendError).

To always make a new value available for future receivers, even if no receiver currently exists, one of the other send methods (send_if_modified, send_modify, or send_replace) can be used instead.

Source

pub fn send_modify<F>(&self, modify: F)
where F: FnOnce(&mut T),

Modifies the watched value unconditionally in-place, notifying all receivers.

This can be useful for modifying the watched value, without having to allocate a new instance. Additionally, this method permits sending values even when there are no receivers.

Prefer to use the more versatile function Self::send_if_modified() if the value is only modified conditionally during the mutable borrow to prevent unneeded change notifications for unmodified values.

§Panics

This function panics when the invocation of the modify closure panics. No receivers are notified when panicking. All changes of the watched value applied by the closure before panicking will be visible in subsequent calls to borrow.

§Examples
use tokio::sync::watch;

struct State {
    counter: usize,
}
let (state_tx, state_rx) = watch::channel(State { counter: 0 });
state_tx.send_modify(|state| state.counter += 1);
assert_eq!(state_rx.borrow().counter, 1);
Source

pub fn send_if_modified<F>(&self, modify: F) -> bool
where F: FnOnce(&mut T) -> bool,

Modifies the watched value conditionally in-place, notifying all receivers only if modified.

This can be useful for modifying the watched value, without having to allocate a new instance. Additionally, this method permits sending values even when there are no receivers.

The modify closure must return true if the value has actually been modified during the mutable borrow. It should only return false if the value is guaranteed to be unmodified despite the mutable borrow.

Receivers are only notified if the closure returned true. If the closure has modified the value but returned false this results in a silent modification, i.e. the modified value will be visible in subsequent calls to borrow, but receivers will not receive a change notification.

Returns the result of the closure, i.e. true if the value has been modified and false otherwise.

§Panics

This function panics when the invocation of the modify closure panics. No receivers are notified when panicking. All changes of the watched value applied by the closure before panicking will be visible in subsequent calls to borrow.

§Examples
use tokio::sync::watch;

struct State {
    counter: usize,
}
let (state_tx, mut state_rx) = watch::channel(State { counter: 1 });
let inc_counter_if_odd = |state: &mut State| {
    if state.counter % 2 == 1 {
        state.counter += 1;
        return true;
    }
    false
};

assert_eq!(state_rx.borrow().counter, 1);

assert!(!state_rx.has_changed().unwrap());
assert!(state_tx.send_if_modified(inc_counter_if_odd));
assert!(state_rx.has_changed().unwrap());
assert_eq!(state_rx.borrow_and_update().counter, 2);

assert!(!state_rx.has_changed().unwrap());
assert!(!state_tx.send_if_modified(inc_counter_if_odd));
assert!(!state_rx.has_changed().unwrap());
assert_eq!(state_rx.borrow_and_update().counter, 2);
Source

pub fn send_replace(&self, value: T) -> T

Sends a new value via the channel, notifying all receivers and returning the previous value in the channel.

This can be useful for reusing the buffers inside a watched value. Additionally, this method permits sending values even when there are no receivers.

§Examples
use tokio::sync::watch;

let (tx, _rx) = watch::channel(1);
assert_eq!(tx.send_replace(2), 1);
assert_eq!(tx.send_replace(3), 2);
Source

pub fn borrow(&self) -> Ref<'_, T>

Returns a reference to the most recently sent value

Outstanding borrows hold a read lock on the inner value. This means that long-lived borrows could cause the producer half to block. It is recommended to keep the borrow as short-lived as possible. Additionally, if you are running in an environment that allows !Send futures, you must ensure that the returned Ref type is never held alive across an .await point, otherwise, it can lead to a deadlock.

§Examples
use tokio::sync::watch;

let (tx, _) = watch::channel("hello");
assert_eq!(*tx.borrow(), "hello");
Source

pub fn is_closed(&self) -> bool

Checks if the channel has been closed. This happens when all receivers have dropped.

§Examples
let (tx, rx) = tokio::sync::watch::channel(());
assert!(!tx.is_closed());

drop(rx);
assert!(tx.is_closed());
Source

pub async fn closed(&self)

Completes when all receivers have dropped.

This allows the producer to get notified when interest in the produced values is canceled and immediately stop doing work. Once a channel is closed, the only way to reopen it is to call Sender::subscribe to get a new receiver.

If the channel becomes closed for a brief amount of time (e.g., the last receiver is dropped and then subscribe is called), then this call to closed might return, but it is also possible that it does not “notice” that the channel was closed for a brief amount of time.

§Cancel safety

This method is cancel safe.

§Examples
use tokio::sync::watch;

#[tokio::main]
async fn main() {
    let (tx, rx) = watch::channel("hello");

    tokio::spawn(async move {
        // use `rx`
        drop(rx);
    });

    // Waits for `rx` to drop
    tx.closed().await;
    println!("the `rx` handles dropped")
}
Source

pub fn subscribe(&self) -> Receiver<T>

Creates a new Receiver connected to this Sender.

All messages sent before this call to subscribe are initially marked as seen by the new Receiver.

This method can be called even if there are no other receivers. In this case, the channel is reopened.

§Examples

The new channel will receive messages sent on this Sender.

use tokio::sync::watch;

#[tokio::main]
async fn main() {
    let (tx, _rx) = watch::channel(0u64);

    tx.send(5).unwrap();

    let rx = tx.subscribe();
    assert_eq!(5, *rx.borrow());

    tx.send(10).unwrap();
    assert_eq!(10, *rx.borrow());
}

The most recent message is considered seen by the channel, so this test is guaranteed to pass.

use tokio::sync::watch;
use tokio::time::Duration;

#[tokio::main]
async fn main() {
    let (tx, _rx) = watch::channel(0u64);
    tx.send(5).unwrap();
    let mut rx = tx.subscribe();

    tokio::spawn(async move {
        // by spawning and sleeping, the message is sent after `main`
        // hits the call to `changed`.
        tokio::time::sleep(Duration::from_millis(10)).await;
        tx.send(100).unwrap();
    });

    rx.changed().await.unwrap();
    assert_eq!(100, *rx.borrow());
}
Source

pub fn receiver_count(&self) -> usize

Returns the number of receivers that currently exist.

§Examples
use tokio::sync::watch;

#[tokio::main]
async fn main() {
    let (tx, rx1) = watch::channel("hello");

    assert_eq!(1, tx.receiver_count());

    let mut _rx2 = rx1.clone();

    assert_eq!(2, tx.receiver_count());
}
Source

pub fn sender_count(&self) -> usize

Returns the number of senders that currently exist.

§Examples
use tokio::sync::watch;

#[tokio::main]
async fn main() {
    let (tx1, rx) = watch::channel("hello");

    assert_eq!(1, tx1.sender_count());

    let tx2 = tx1.clone();

    assert_eq!(2, tx1.sender_count());
    assert_eq!(2, tx2.sender_count());
}
Source

pub fn same_channel(&self, other: &Self) -> bool

Returns true if senders belong to the same channel.

§Examples
let (tx, rx) = tokio::sync::watch::channel(true);
let tx2 = tx.clone();
assert!(tx.same_channel(&tx2));

let (tx3, rx3) = tokio::sync::watch::channel(true);
assert!(!tx3.same_channel(&tx2));

Trait Implementations§

Source§

impl<T> Clone for Sender<T>

Source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug> Debug for Sender<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Default> Default for Sender<T>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<T> Drop for Sender<T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<T> Freeze for Sender<T>

§

impl<T> RefUnwindSafe for Sender<T>

§

impl<T> Send for Sender<T>
where T: Send + Sync,

§

impl<T> Sync for Sender<T>
where T: Send + Sync,

§

impl<T> Unpin for Sender<T>

§

impl<T> UnwindSafe for Sender<T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.