Структура Sender
pub struct Sender<T> { /* private fields */ }
sync.Реализации
impl<T> Sender<T>
pub fn new(init: T) -> Self
Создаёт отправляющую половину канала watch.
Информацию об ошибках при вызове этой функции см. в документации watch::channel. Обратите внимание: попытка отправить значение, когда получателей нет, приведёт к ошибке.
Примеры
let sender = tokio::sync::watch::Sender::new(0u8);
assert!(sender.send(3).is_err());
let _rec = sender.subscribe();
assert!(sender.send(4).is_ok());pub fn send(&self, value: T) -> Result<(), SendError<T>>
Отправляет новое значение через канал, уведомляя всех получателей.
Этот метод завершается ошибкой, если канал закрыт, то есть если все получатели были удалены. Канал можно открыть снова с помощью метода subscribe. Однако, если вызов send завершается ошибкой, значение не становится доступным для будущих получателей (оно возвращается вместе с SendError).
Чтобы новое значение всегда становилось доступным для будущих получателей, даже если в данный момент получателей нет, можно использовать один из других методов отправки: send_if_modified, send_modify или send_replace.
pub fn send_modify<F>(&self, modify: F)
Безусловно изменяет наблюдаемое значение на месте, уведомляя всех получателей.
Это может быть полезно для изменения наблюдаемого значения без выделения памяти под новый экземпляр. Кроме того, этот метод позволяет отправлять значения даже тогда, когда получателей нет.
Если значение изменяется только условно во время изменяемого заимствования, предпочтительнее использовать более универсальную функцию Self::send_if_modified(), чтобы избежать ненужных уведомлений об изменении неизменённых значений.
Паника
Эта функция вызывает панику, если при вызове замыкания modify возникает паника. При панике получатели не уведомляются. Все изменения наблюдаемого значения, внесённые замыканием до возникновения паники, будут видны при последующих вызовах borrow.
Примеры
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);pub fn send_if_modified<F>(&self, modify: F) -> bool
Условно изменяет наблюдаемое значение на месте, уведомляя всех получателей только в случае изменения.
Это может быть полезно для изменения наблюдаемого значения без выделения памяти под новый экземпляр. Кроме того, этот метод позволяет отправлять значения даже тогда, когда получателей нет.
Замыкание modify должно вернуть true, если значение действительно было изменено во время изменяемого заимствования. Оно должно возвращать false только в том случае, если гарантируется, что значение не изменилось, несмотря на изменяемое заимствование.
Получатели уведомляются только в том случае, если замыкание вернуло true. Если замыкание изменило значение, но вернуло false, это приводит к тихому изменению: изменённое значение будет видно при последующих вызовах borrow, но получатели не получат уведомление об изменении.
Возвращает результат замыкания: true, если значение было изменено, и false в противном случае.
Паника
Эта функция вызывает панику, если при вызове замыкания modify возникает паника. При панике получатели не уведомляются. Все изменения наблюдаемого значения, внесённые замыканием до возникновения паники, будут видны при последующих вызовах borrow.
Примеры
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);pub fn send_replace(&self, value: T) -> T
Отправляет новое значение через канал, уведомляя всех получателей и возвращая предыдущее значение в канале.
Это может быть полезно для повторного использования буферов внутри наблюдаемого значения. Кроме того, этот метод позволяет отправлять значения даже тогда, когда получателей нет.
Примеры
use tokio::sync::watch;
let (tx, _rx) = watch::channel(1);
assert_eq!(tx.send_replace(2), 1);
assert_eq!(tx.send_replace(3), 2);pub fn borrow(&self) -> Ref<'_, T>
Возвращает ссылку на последнее отправленное значение
Незавершённые заимствования удерживают блокировку для чтения внутреннего значения. Это означает, что длительные заимствования могут привести к блокировке отправителя. Рекомендуется удерживать заимствование как можно меньше. Кроме того, если вы работаете в среде, допускающей !Send futures, необходимо убедиться, что возвращённый тип Ref никогда не остаётся активным во время точки .await, иначе это может привести к взаимной блокировке.
Примеры
use tokio::sync::watch;
let (tx, _) = watch::channel("hello");
assert_eq!(*tx.borrow(), "hello");pub fn is_closed(&self) -> bool
Проверяет, закрыт ли канал. Это происходит, когда все получатели уничтожены.
Примеры
let (tx, rx) = tokio::sync::watch::channel(());
assert!(!tx.is_closed());
drop(rx);
assert!(tx.is_closed());pub async fn closed(&self)
Завершается, когда все получатели уничтожены.
Это позволяет отправителю получать уведомление об отмене интереса к отправляемым значениям и немедленно прекращать работу. После закрытия канала открыть его снова можно только вызовом Sender::subscribe, чтобы получить нового получателя.
Если канал закрывается на короткое время (например, последний получатель уничтожается, а затем вызывается subscribe), этот вызов closed может завершиться, но также возможно, что он не «заметит», что канал был ненадолго закрыт.
Безопасность отмены
Этот метод безопасен при отмене.
Примеры
use tokio::sync::watch;
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")pub fn subscribe(&self) -> Receiver<T>
Создаёт новый Receiver, подключённый к этому Sender.
Все сообщения, отправленные до этого вызова subscribe, изначально помечаются новым Receiver как просмотренные.
Этот метод можно вызвать, даже если других получателей нет. В этом случае канал открывается снова.
Примеры
Новый канал будет получать сообщения, отправленные в этот Sender.
use tokio::sync::watch;
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());Последнее сообщение считается просмотренным каналом, поэтому эта проверка гарантированно пройдёт.
use tokio::sync::watch;
use tokio::time::Duration;
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());pub fn receiver_count(&self) -> usize
Возвращает количество существующих в данный момент получателей.
Примеры
use tokio::sync::watch;
let (tx, rx1) = watch::channel("hello");
assert_eq!(1, tx.receiver_count());
let mut _rx2 = rx1.clone();
assert_eq!(2, tx.receiver_count());pub fn sender_count(&self) -> usize
Возвращает количество существующих в данный момент отправителей.
Примеры
use tokio::sync::watch;
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());pub fn same_channel(&self, other: &Self) -> bool
Возвращает true, если отправители принадлежат одному каналу.
Примеры
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));Реализации трейтов
impl<T> Clone for Sender<T>
fn clone_from(&mut self, source: &Self)
source. Подробнее
Автоматические реализации трейтов
impl<T> !RefUnwindSafe for Sender<T>
impl<T> !UnwindSafe for Sender<T>
impl<T> Freeze for Sender<T>
impl<T> Send for Sender<T>
impl<T> Sync for Sender<T>
impl<T> Unpin for Sender<T>
impl<T> UnsafeUnpin for Sender<T>
Реализации для всех типов
impl<T> BorrowMut<T> for Twhere T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
impl<T> CloneToUninit for Twhere T: Clone,
unsafe fn clone_to_uninit(&self, dest: *mut u8)
clone_to_uninit)
impl<T> Instrument for T
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
impl<T> ToOwned for Twhere T: Clone,
type Owned = T
fn to_owned(&self) -> T
fn clone_into(&self, target: &mut T)
impl<T> WithSubscriber for T
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ
Subscriber к этому типу и возвращает обёртку WithDispatch. Подробнее
MIT License
Copyright © Tokio Contributors
https://docs.rs/tokio/1.53.1/tokio/sync/watch/struct.Sender.html