tokio_timer/interval.rs
1use Delay;
2
3use clock;
4
5use futures::{Future, Poll, Stream};
6
7use std::time::{Duration, Instant};
8
9/// A stream representing notifications at fixed interval
10#[derive(Debug)]
11pub struct Interval {
12 /// Future that completes the next time the `Interval` yields a value.
13 delay: Delay,
14
15 /// The duration between values yielded by `Interval`.
16 duration: Duration,
17}
18
19impl Interval {
20 /// Create a new `Interval` that starts at `at` and yields every `duration`
21 /// interval after that.
22 ///
23 /// Note that when it starts, it produces item too.
24 ///
25 /// The `duration` argument must be a non-zero duration.
26 ///
27 /// # Panics
28 ///
29 /// This function panics if `duration` is zero.
30 pub fn new(at: Instant, duration: Duration) -> Interval {
31 assert!(
32 duration > Duration::new(0, 0),
33 "`duration` must be non-zero."
34 );
35
36 Interval::new_with_delay(Delay::new(at), duration)
37 }
38
39 /// Creates new `Interval` that yields with interval of `duration`.
40 ///
41 /// The function is shortcut for `Interval::new(Instant::now() + duration, duration)`.
42 ///
43 /// The `duration` argument must be a non-zero duration.
44 ///
45 /// # Panics
46 ///
47 /// This function panics if `duration` is zero.
48 pub fn new_interval(duration: Duration) -> Interval {
49 Interval::new(clock::now() + duration, duration)
50 }
51
52 pub(crate) fn new_with_delay(delay: Delay, duration: Duration) -> Interval {
53 Interval { delay, duration }
54 }
55}
56
57impl Stream for Interval {
58 type Item = Instant;
59 type Error = ::Error;
60
61 fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
62 // Wait for the delay to be done
63 let _ = try_ready!(self.delay.poll());
64
65 // Get the `now` by looking at the `delay` deadline
66 let now = self.delay.deadline();
67
68 // The next interval value is `duration` after the one that just
69 // yielded.
70 self.delay.reset(now + self.duration);
71
72 // Return the current instant
73 Ok(Some(now).into())
74 }
75}