pub(crate) struct Timer<R: SleepProvider> {
sleep_prov: R,
parameters: Option<PreparedParameters>,
selected_timeout: Option<Duration>,
trigger_at: Option<Instant>,
waker: Option<R::SleepFuture>,
}Expand description
Timer that organises wakeups when channel padding should be sent
Use next() to find when to send padding, and
note_cell_sent() to reset the timeout when data flows.
A Timer can be in “disabled” state, in which case next() never completes.
Timer must be pinned before use
(this allows us to avoid involving the allocator when we reschedule).
Fields§
§sleep_prov: R§parameters: Option<PreparedParameters>Parameters controlling distribution of padding time intervals
Can be None to mean the timing parameters are set to infinity.
selected_timeout: Option<Duration>Gap that we intend to leave between last sent cell, and the padding
We only resample this (calculating a new random delay) after the previous timeout actually expired.
None if the timer is disabled.
(This can be done explicitly, but also occurs on time calculation overflow.)
Invariants: this field may be Some or None regardless of the values
of other fields. If this field is None then the values in trigger_at
and waker are unspecified.
trigger_at: Option<Instant>Absolute time at which we should send padding
None if cells more recently sent than we were polled.
That would mean that we are currently moving data out through this channel.
The absolute timeout will need to be recalculated when the data flow pauses.
Some means our next has been demanded recently.
Then trigger_at records the absolute timeout at which we should send padding,
which was calculated the first time we were polled (after data).
Invariants: the value in this field is meaningful only if selected_timeout
is Some.
If selected_timeout is Some, and trigger_at is therefore valid,
it is (obviously) no later than selected_timeout from now.
See also waker.
waker: Option<R::SleepFuture>Actual waker from the SleepProvider
This is created and updated lazily, because we suspect that with some runtimes setting timeouts may be slow. Lazy updating means that with intermittent data traffic, we do not keep scheduling, descheduling, and adjusting, a wakeup time.
Invariants:
If selected_timeout is Some,
the time at which this waker will trigger here is never later than trigger_at,
and never later than selected_timeout from now.
The wakeup time here may well be earlier than trigger_at,
and sooner than selected_timeout from now. It may even be in the past.
When we wake up and discover this situation, we reschedule a new waker.
If selected_timeout is None, the value is unspecified.
We may retain a Some in this case so that if SleepProvider is enhanced to
support rescheduling, we can do that without making a new SleepFuture
(and without completely reorganising this the Timer state structure.)
Implementations§
Source§impl<R: SleepProvider> Timer<R>
impl<R: SleepProvider> Timer<R>
pub(crate) fn project<'pin>( self: Pin<&'pin mut Self>, ) -> PaddingTimerProj<'pin, R>
pub(crate) fn project_ref<'pin>( self: Pin<&'pin Self>, ) -> __TimerProjectionRef<'pin, R>
Source§impl<R: SleepProvider> Timer<R>
impl<R: SleepProvider> Timer<R>
Sourcepub(crate) fn new(sleep_prov: R, parameters: Parameters) -> Result<Self>
pub(crate) fn new(sleep_prov: R, parameters: Parameters) -> Result<Self>
Create a new Timer
Sourcepub(crate) fn new_disabled(
sleep_prov: R,
parameters: Option<Parameters>,
) -> Result<Self>
pub(crate) fn new_disabled( sleep_prov: R, parameters: Option<Parameters>, ) -> Result<Self>
Create a new Timer which starts out disabled
Sourcepub(crate) fn enable(self: &mut Pin<&mut Self>)
pub(crate) fn enable(self: &mut Pin<&mut Self>)
Enable this Timer
(If the timer was disabled, the timeout will only start to run when next()
is next polled.)
Idempotent.
Sourcepub(crate) fn reconfigure(
self: &mut Pin<&mut Self>,
parameters: &Parameters,
) -> Result<()>
pub(crate) fn reconfigure( self: &mut Pin<&mut Self>, parameters: &Parameters, ) -> Result<()>
Set this Timer’s parameters
Will not enable or disable the timer; that must be done separately if desired.
The effect may not be immediate: if we are already in a gap between cells, that existing gap may not be adjusted. (We don’t restart the timer since that would very likely result in a gap longer than either of the configured values.)
Idempotent.
Sourcepub(crate) fn is_enabled(&self) -> bool
pub(crate) fn is_enabled(&self) -> bool
Enquire whether this Timer is currently enabled
Sourcefn select_fresh_timeout(self: Pin<&mut Self>)
fn select_fresh_timeout(self: Pin<&mut Self>)
Select a fresh timeout (and enable, if possible)
Sourcepub(crate) fn note_cell_sent(self: &mut Pin<&mut Self>)
pub(crate) fn note_cell_sent(self: &mut Pin<&mut Self>)
Note that data has been sent (ie, reset the timeout, delaying the next padding)
Sourcefn prepare_to_sleep(
self: Pin<&mut Self>,
now: Option<Instant>,
) -> SleepInstructions<'_, R>
fn prepare_to_sleep( self: Pin<&mut Self>, now: Option<Instant>, ) -> SleepInstructions<'_, R>
Calculate when to send padding, and return a suitable waker
In the usual case returns SleepInstructions::Waker.
Sourcepub(crate) fn next(
self: Pin<&mut Self>,
) -> impl FusedFuture<Output = Padding> + '_
pub(crate) fn next( self: Pin<&mut Self>, ) -> impl FusedFuture<Output = Padding> + '_
Wait until we should next send padding, and then return the padding message
Should be used as a low-priority branch within select_biased!.
(next() has to be selected on, along with other possible events, in the
main loop, so that the padding timer runs concurrently with other processing;
and it should be in a low-priority branch of select_biased! as an optimisation:
that avoids calculating timeouts etc. until necessary,
i.e. it calculates them only when the main loop would otherwise block.)
The returned future is async-cancel-safe, but once it yields, the padding must actually be sent.
Sourceasync fn next_inner(self: Pin<&mut Self>) -> Padding
async fn next_inner(self: Pin<&mut Self>) -> Padding
Wait until we should next send padding (not FusedFuture)
Callers wants a FusedFuture because select! needs one.
Trait Implementations§
impl<'pin, R: SleepProvider> Unpin for Timer<R>where
PinnedFieldsOf<__Timer<'pin, R>>: Unpin,
Auto Trait Implementations§
impl<R> Freeze for Timer<R>
impl<R> RefUnwindSafe for Timer<R>
impl<R> Send for Timer<R>
impl<R> Sync for Timer<R>
impl<R> UnsafeUnpin for Timer<R>
impl<R> UnwindSafe for Timer<R>
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
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
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§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.Source§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.Source§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.Source§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.Source§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.Source§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.Source§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.Source§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.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§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 moreSource§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§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 moreSource§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 moreSource§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
Source§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
Source§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.Source§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.Source§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.Source§impl<T> PossiblyOption<T> for T
impl<T> PossiblyOption<T> for T
Source§impl<T> Tap for T
impl<T> Tap for T
Source§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 moreSource§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 moreSource§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 moreSource§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 moreSource§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 moreSource§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 moreSource§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.Source§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.Source§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.Source§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.Source§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.Source§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.Source§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.