1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//! Cooperative sleep — a [`SleepingTask`] that yields [`TaskStatus::Delayed`].
//!
//! Use [`sleep`](crate::valtron::executors::sleep()) (returns the task directly)
//! or [`sleep_async`](crate::valtron::executors::sleep_async()) (returns a
//! `Future` via `execute()` + `into_ready_future()`).
use std::time::{Duration, Instant};
use crate::valtron::{Ctx, TaskIterator, TaskStatus};
/// A [`TaskIterator`] that yields [`TaskStatus::Delayed(remaining)`] until
/// the deadline passes, then returns `None`.
pub struct SleepingTask {
deadline: Instant,
}
impl SleepingTask {
#[must_use]
pub fn new(deadline: Instant) -> Self {
Self { deadline }
}
#[must_use]
pub fn sleep(duration: Duration) -> Self {
Self {
deadline: Instant::now()
.checked_add(duration)
.unwrap_or_else(|| Instant::now() + Duration::from_secs(1_000_000)),
}
}
#[must_use]
pub fn deadline(&self) -> Instant {
self.deadline
}
}
impl TaskIterator for SleepingTask {
type Ready = ();
type Pending = ();
fn next_status(&mut self, _ctx: Ctx) -> Option<TaskStatus<(), ()>> {
let now = Instant::now();
if now >= self.deadline {
None
} else {
Some(TaskStatus::Delayed(self.deadline - now))
}
}
}