You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
rsh/src/ext/sync.rs

75 lines
2.0 KiB

//! Syncronisation helpers
use super::*;
use futures::{
Future,
};
use tokio::time::Duration;
/// Force a future to take *at least* a specific amount of time to complete.
///
/// If the future takes longer than `time` to complete, no additional delay is added.
/// If `time` is zero, no delay is added.
///
/// # Panics
/// The returned future will panic if
/// * The future itself panics
/// * We are unable to convert the future's duration from `chrono`'s duration span to std's duration span
pub fn timesync<'a, T, F>(future: F, time: Duration) -> impl Future<Output = T> + 'a
where F: Future<Output=T> + 'a
{
use chrono::prelude::*;
#[cold]
#[inline(never)]
fn _panic_failed_tmconv(orig: chrono::Duration, error: impl Into<eyre::Report>)
{
panic!("Failed to convert chrono duration span {:?} to std duration span: {}", orig, error.into());
}
async move {
let now = Utc::now();
let r = future.await;
if time.is_zero() {
return r;
}
let after = Utc::now();
let duration = after - now;
match duration.to_std() {
Ok(taken)
if taken < time => {
// Delay for the remaining time
tokio::time::delay_for(time - taken).await;
},
Err(error) => _panic_failed_tmconv(duration, error),
// At least `time` has passed
_ => (),
}
r
}
}
pub trait TimeSyncExt<'a>: Future + Sized + 'a
{
type OutputFuture: Future<Output = Self::Output> + 'a;
fn pad_time(self, time: Duration) -> Self::OutputFuture;
}
#[cfg(nightly)]
impl<'a, F> TimeSyncExt<'a> for F
where F: Future + 'a
{
//#[cfg(nightly)]
type OutputFuture = impl Future<Output = Self::Output> + 'a;
//#[cfg(not(nightly))]
//type OutputFuture = futures::future::BoxFuture<'a, Self::Output>; //TODO: Requires `Send` bound for some reason.
fn pad_time(self, time: Duration) -> Self::OutputFuture {
/*#[cfg(not(nightly))] {
use futures::prelude::*;
return timesync(self, time).boxed();
}
#[cfg(nightly)] {
return*/ timesync(self, time)
//}
}
}