Created
February 21, 2022 02:06
-
-
Save Porges/72dc5e2fdac91a511da5f1d7cf354611 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use futures_util::Future; | |
use tokio::time::{self, Duration, Instant, MissedTickBehavior}; | |
pub struct Pacer { | |
period: Duration, | |
total_duration: Duration, | |
behavior: MissedTickBehavior, | |
} | |
impl Pacer { | |
pub fn new(period: Duration, total_duration: Duration, behavior: MissedTickBehavior) -> Self { | |
Self { | |
period, | |
total_duration, | |
behavior, | |
} | |
} | |
pub async fn run<F, Fut, E>(&self, mut task: F) -> Result<(), E> | |
where | |
F: FnMut() -> Fut, | |
Fut: Future<Output = Result<(), E>>, | |
{ | |
let mut interval = time::interval(self.period); | |
interval.set_missed_tick_behavior(self.behavior); | |
let end = Instant::now() + self.total_duration; | |
loop { | |
task().await?; | |
if Instant::now() >= end { | |
return Ok(()); | |
} | |
interval.tick().await; | |
} | |
} | |
} | |
#[tokio::main] | |
async fn main() { | |
struct Task { | |
last_invoked: Option<Instant>, | |
} | |
impl Task { | |
fn new() -> Self { | |
Self { last_invoked: None } | |
} | |
fn tick(&mut self) -> impl Future<Output = anyhow::Result<()>> { | |
let now = Instant::now(); | |
let since_last = self.last_invoked.map(|i| now.duration_since(i)); | |
println!(".{:?}", since_last); | |
self.last_invoked = Some(now); | |
// pretend this method would do its own .await | |
async { Ok(()) } | |
} | |
} | |
let pacer = Pacer::new( | |
Duration::from_millis(1), | |
Duration::from_millis(50), | |
MissedTickBehavior::Delay, | |
); | |
let mut task = Task::new(); | |
let started = Instant::now(); | |
let _ = pacer | |
.run(move || task.tick()) | |
.await | |
.expect("Task should not produce an error"); | |
println!("total elapsed: {:?}", started.elapsed()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment