micromegas 0.7.0

Micromegas is a scalable observability solution.
Documentation
use anyhow::{Context, Result};
use async_trait::async_trait;
use chrono::{DateTime, DurationRound, TimeDelta, Utc};
use micromegas_tracing::prelude::*;
use std::sync::Arc;

#[async_trait]
pub trait TaskCallback: Send + Sync {
    async fn run(&self, task_scheduled_time: DateTime<Utc>) -> Result<()>;
}

pub struct CronTask {
    pub name: String,
    pub period: TimeDelta,
    pub offset: TimeDelta,
    pub callback: Arc<dyn TaskCallback>,
    pub next_run: DateTime<Utc>,
}

impl CronTask {
    pub fn new(
        name: String,
        period: TimeDelta,
        offset: TimeDelta,
        callback: Arc<dyn TaskCallback>,
    ) -> Result<Self> {
        let now = Utc::now();
        let next_run = now.duration_trunc(period)? + period + offset;
        Ok(Self {
            name,
            period,
            offset,
            callback,
            next_run,
        })
    }

    pub async fn tick(&mut self) -> Result<()> {
        let now = Utc::now();
        info!("running scheduled task name={}", &self.name);
        imetric!(
            "task_tick_delay",
            "ns",
            (now - self.next_run)
                .num_nanoseconds()
                .with_context(|| "get tick delay as ns")? as u64
        );
        let task_time = self.next_run;
        self.next_run += self.period;
        self.callback
            .run(task_time)
            .await
            .with_context(|| "TaskDef::tick")?;
        Ok(())
    }
}