pub struct ForkChoiceNotifications<T = Header>(pub Receiver<Option<SealedHeader<T>>>);
Expand description
Wrapper around a broadcast receiver that receives fork choice notifications.
Tuple Fields§
§0: Receiver<Option<SealedHeader<T>>>
Methods from Deref<Target = Receiver<Option<SealedHeader<T>>>>§
pub fn borrow(&self) -> Ref<'_, T>
pub fn borrow(&self) -> Ref<'_, T>
Returns a reference to the most recently sent value.
This method does not mark the returned value as seen, so future calls to
changed
may return immediately even if you have already seen the
value with a call to borrow
.
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.
The priority policy of the lock is dependent on the underlying lock
implementation, and this type does not guarantee that any particular policy
will be used. In particular, a producer which is waiting to acquire the lock
in send
might or might not block concurrent calls to borrow
, e.g.:
Potential deadlock example
// Task 1 (on thread A) | // Task 2 (on thread B)
let _ref1 = rx.borrow(); |
| // will block
| let _ = tx.send(());
// may deadlock |
let _ref2 = rx.borrow(); |
For more information on when to use this method versus
borrow_and_update
, see here.
§Examples
use tokio::sync::watch;
let (_, rx) = watch::channel("hello");
assert_eq!(*rx.borrow(), "hello");
pub fn borrow_and_update(&mut self) -> Ref<'_, T>
pub fn borrow_and_update(&mut self) -> Ref<'_, T>
Returns a reference to the most recently sent value and marks that value as seen.
This method marks the current value as seen. Subsequent calls to changed
will not return immediately until the [Sender
] has modified the shared
value again.
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.
The priority policy of the lock is dependent on the underlying lock
implementation, and this type does not guarantee that any particular policy
will be used. In particular, a producer which is waiting to acquire the lock
in send
might or might not block concurrent calls to borrow
, e.g.:
Potential deadlock example
// Task 1 (on thread A) | // Task 2 (on thread B)
let _ref1 = rx1.borrow_and_update(); |
| // will block
| let _ = tx.send(());
// may deadlock |
let _ref2 = rx2.borrow_and_update(); |
For more information on when to use this method versus borrow
, see
here.
pub fn has_changed(&self) -> Result<bool, RecvError>
pub fn has_changed(&self) -> Result<bool, RecvError>
Checks if this channel contains a message that this receiver has not yet seen. The new value is not marked as seen.
Although this method is called has_changed
, it does not check new
messages for equality, so this call will return true even if the new
message is equal to the old message.
Returns an error if the channel has been closed.
§Examples
use tokio::sync::watch;
#[tokio::main]
async fn main() {
let (tx, mut rx) = watch::channel("hello");
tx.send("goodbye").unwrap();
assert!(rx.has_changed().unwrap());
assert_eq!(*rx.borrow_and_update(), "goodbye");
// The value has been marked as seen
assert!(!rx.has_changed().unwrap());
drop(tx);
// The `tx` handle has been dropped
assert!(rx.has_changed().is_err());
}
pub fn mark_changed(&mut self)
pub fn mark_changed(&mut self)
Marks the state as changed.
After invoking this method has_changed()
returns true
and changed()
returns
immediately, regardless of whether a new value has been sent.
This is useful for triggering an initial change notification after subscribing to synchronize new receivers.
pub fn mark_unchanged(&mut self)
pub fn mark_unchanged(&mut self)
Marks the state as unchanged.
The current value will be considered seen by the receiver.
This is useful if you are not interested in the current value visible in the receiver.
pub async fn changed(&mut self) -> Result<(), RecvError>
pub async fn changed(&mut self) -> Result<(), RecvError>
Waits for a change notification, then marks the newest value as seen.
If the newest value in the channel has not yet been marked seen when
this method is called, the method marks that value seen and returns
immediately. If the newest value has already been marked seen, then the
method sleeps until a new message is sent by the Sender
connected to
this Receiver
, or until the Sender
is dropped.
This method returns an error if and only if the Sender
is dropped.
For more information, see Change notifications in the module-level documentation.
§Cancel safety
This method is cancel safe. If you use it as the event in a
tokio::select!
statement and some other branch
completes first, then it is guaranteed that no values have been marked
seen by this call to changed
.
§Examples
use tokio::sync::watch;
#[tokio::main]
async fn main() {
let (tx, mut rx) = watch::channel("hello");
tokio::spawn(async move {
tx.send("goodbye").unwrap();
});
assert!(rx.changed().await.is_ok());
assert_eq!(*rx.borrow_and_update(), "goodbye");
// The `tx` handle has been dropped
assert!(rx.changed().await.is_err());
}
pub async fn wait_for(
&mut self,
f: impl FnMut(&T) -> bool,
) -> Result<Ref<'_, T>, RecvError>
pub async fn wait_for( &mut self, f: impl FnMut(&T) -> bool, ) -> Result<Ref<'_, T>, RecvError>
Waits for a value that satisfies the provided condition.
This method will call the provided closure whenever something is sent on
the channel. Once the closure returns true
, this method will return a
reference to the value that was passed to the closure.
Before wait_for
starts waiting for changes, it will call the closure
on the current value. If the closure returns true
when given the
current value, then wait_for
will immediately return a reference to
the current value. This is the case even if the current value is already
considered seen.
The watch channel only keeps track of the most recent value, so if
several messages are sent faster than wait_for
is able to call the
closure, then it may skip some updates. Whenever the closure is called,
it will be called with the most recent value.
When this function returns, the value that was passed to the closure
when it returned true
will be considered seen.
If the channel is closed, then wait_for
will return a RecvError
.
Once this happens, no more messages can ever be sent on the channel.
When an error is returned, it is guaranteed that the closure has been
called on the last value, and that it returned false
for that value.
(If the closure returned true
, then the last value would have been
returned instead of the error.)
Like the borrow
method, the returned borrow holds 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. See the documentation of borrow
for more information on
this.
§Examples
use tokio::sync::watch;
#[tokio::main]
async fn main() {
let (tx, _rx) = watch::channel("hello");
tx.send("goodbye").unwrap();
// here we subscribe to a second receiver
// now in case of using `changed` we would have
// to first check the current value and then wait
// for changes or else `changed` would hang.
let mut rx2 = tx.subscribe();
// in place of changed we have use `wait_for`
// which would automatically check the current value
// and wait for changes until the closure returns true.
assert!(rx2.wait_for(|val| *val == "goodbye").await.is_ok());
assert_eq!(*rx2.borrow(), "goodbye");
}
pub fn same_channel(&self, other: &Receiver<T>) -> bool
pub fn same_channel(&self, other: &Receiver<T>) -> bool
Returns true
if receivers belong to the same channel.
§Examples
let (tx, rx) = tokio::sync::watch::channel(true);
let rx2 = rx.clone();
assert!(rx.same_channel(&rx2));
let (tx3, rx3) = tokio::sync::watch::channel(true);
assert!(!rx3.same_channel(&rx2));
Trait Implementations§
Source§impl<T: Debug> Debug for ForkChoiceNotifications<T>
impl<T: Debug> Debug for ForkChoiceNotifications<T>
Source§impl<T> Deref for ForkChoiceNotifications<T>
impl<T> Deref for ForkChoiceNotifications<T>
Auto Trait Implementations§
impl<T> Freeze for ForkChoiceNotifications<T>
impl<T = Header> !RefUnwindSafe for ForkChoiceNotifications<T>
impl<T> Send for ForkChoiceNotifications<T>
impl<T> Sync for ForkChoiceNotifications<T>
impl<T> Unpin for ForkChoiceNotifications<T>
impl<T = Header> !UnwindSafe for ForkChoiceNotifications<T>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.§impl<T> TryConv for T
impl<T> TryConv for T
§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where
S: Into<Dispatch>,
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where
S: Into<Dispatch>,
§fn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
impl<T> ErasedDestructor for Twhere
T: 'static,
impl<T> MaybeDebug for Twhere
T: Debug,
impl<T> MaybeSendSync for T
Layout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...)
attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 16 bytes