Skip to content

Commit

Permalink
feat: impl debug for dyn IntervalGenerator trait
Browse files Browse the repository at this point in the history
  • Loading branch information
paomian committed Oct 19, 2023
1 parent 0ea537f commit 5215edc
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 20 deletions.
4 changes: 2 additions & 2 deletions src/common/greptimedb-telemetry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use std::sync::Arc;
use std::time::Duration;

use common_runtime::error::{Error, Result};
use common_runtime::{BoxedTaskFunction, ImmediatelyInterval, RepeatedTask, TaskFunction};
use common_runtime::{BoxedTaskFunction, FirstZeroInterval, RepeatedTask, TaskFunction};
use common_telemetry::{debug, info};
use reqwest::{Client, Response};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -58,7 +58,7 @@ impl GreptimeDBTelemetryTask {
should_report: Arc<AtomicBool>,
) -> Self {
GreptimeDBTelemetryTask::Enable((
RepeatedTask::new(ImmediatelyInterval::new(interval), task_fn),
RepeatedTask::new(FirstZeroInterval::new(interval), task_fn),
should_report,
))
}
Expand Down
4 changes: 1 addition & 3 deletions src/common/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,5 @@ pub use global::{
spawn_read, spawn_write, write_runtime,
};

pub use crate::repeated_task::{
BoxedTaskFunction, ImmediatelyInterval, RepeatedTask, TaskFunction,
};
pub use crate::repeated_task::{BoxedTaskFunction, FirstZeroInterval, RepeatedTask, TaskFunction};
pub use crate::runtime::{Builder, JoinError, JoinHandle, Runtime};
44 changes: 29 additions & 15 deletions src/common/runtime/src/repeated_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,41 @@ pub type BoxedTaskFunction<E> = Box<dyn TaskFunction<E> + Send + Sync + 'static>
struct TaskInner<E> {
/// The repeated task handle. This handle is Some if the task is started.
task_handle: Option<JoinHandle<()>>,

/// The task_fn to run. This is Some if the task is not started.
task_fn: Option<BoxedTaskFunction<E>>,

/// Generates the next interval.
interval_generator: Option<Box<dyn IntervalGenerator>>,
}

pub trait IntervalGenerator: Send + Sync {
/// return the next interval.
fn next(&mut self) -> Duration;
fn is_regular(&self) -> bool {
true

/// return whether the interval is regular and the interval if it is regular.
fn is_regular(&self) -> (bool, Option<Duration>);
}

impl std::fmt::Debug for dyn IntervalGenerator {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut binding = f.debug_struct("IntervalGenerator");
let mut builder = binding.field("is_regular", &self.is_regular().0);
if self.is_regular().0 {
builder = builder.field("interval", &self.is_regular().1);
}
builder.finish()
}
}

impl IntervalGenerator for Duration {
fn next(&mut self) -> Duration {
*self
}

fn is_regular(&self) -> (bool, Option<Duration>) {
(true, Some(*self))
}
}

impl From<Duration> for Box<dyn IntervalGenerator> {
Expand All @@ -66,12 +84,12 @@ impl From<Duration> for Box<dyn IntervalGenerator> {
}
}

pub struct ImmediatelyInterval {
pub struct FirstZeroInterval {
first: bool,
interval: Duration,
}

impl ImmediatelyInterval {
impl FirstZeroInterval {
pub fn new(interval: Duration) -> Self {
Self {
first: false,
Expand All @@ -80,7 +98,7 @@ impl ImmediatelyInterval {
}
}

impl IntervalGenerator for ImmediatelyInterval {
impl IntervalGenerator for FirstZeroInterval {
fn next(&mut self) -> Duration {
if !self.first {
self.first = true;
Expand All @@ -90,13 +108,13 @@ impl IntervalGenerator for ImmediatelyInterval {
}
}

fn is_regular(&self) -> bool {
false
fn is_regular(&self) -> (bool, Option<Duration>) {
(false, None)
}
}

impl From<ImmediatelyInterval> for Box<dyn IntervalGenerator> {
fn from(value: ImmediatelyInterval) -> Self {
impl From<FirstZeroInterval> for Box<dyn IntervalGenerator> {
fn from(value: FirstZeroInterval) -> Self {
Box::new(value)
}
}
Expand Down Expand Up @@ -163,11 +181,7 @@ impl<E: ErrorExt + 'static> RepeatedTask<E> {
// Safety: The task is not started.
let mut task_fn = inner.task_fn.take().unwrap();
let interval = interval_generator.next();
let interval_str = if interval_generator.is_regular() {
format!("{:?}", interval)
} else {
"irregular".to_string()
};
let interval_str = format!("{:?}", interval_generator);
// TODO(hl): Maybe spawn to a blocking runtime.
let handle = runtime.spawn(async move {
let sleep = tokio::time::sleep(interval);
Expand Down Expand Up @@ -269,7 +283,7 @@ mod tests {

let n = Arc::new(AtomicI32::new(0));
let task_fn = TickTask { n: n.clone() };
let interval = ImmediatelyInterval::new(Duration::from_millis(100));
let interval = FirstZeroInterval::new(Duration::from_millis(100));
let task = RepeatedTask::new(interval, Box::new(task_fn));

task.start(crate::bg_runtime()).unwrap();
Expand Down

0 comments on commit 5215edc

Please sign in to comment.