-
Notifications
You must be signed in to change notification settings - Fork 143
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[STATS] Update stats architecture (#891)
Main goal: allow more complex relations between charts Main changes overview: - flexible framework for data retrieval, processing, and storage - flexible data dependencies with synchronized and efficient updates - config reorganization and changes (see `migration` in config files folder for more) Tech debt mitigated: - `order` parameter in config changed to list; overrideable with env - compilation without test-utils fix (tests can be run w/o the feature) - remove duplication of configs (in runtime) - deprecate toml config - more accurate metrics collection (exclude mutex waiting) - fix fill logic when to in request is None - update some dependencies versions Collateral changes: - querying get_chart_data (now `get_line_chart_data`) without `fill_missing_dates` now returns data only within range according to missing date policy (for FillPrevious the first data point is moved from outside the range, if needed) (previously it could add a point before the range)
- Loading branch information
Showing
143 changed files
with
10,858 additions
and
5,933 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[package] | ||
name = "blockscout-metrics-tools" | ||
version = "0.1.0" | ||
description = "Collection of tools helpful for metrics collection" | ||
license = "MIT" | ||
repository = "https://github.com/blockscout/blockscout-rs" | ||
edition = "2021" | ||
keywords = ["metrics", "time"] | ||
categories = ["date-and-time"] | ||
|
||
[dependencies] |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
use std::time::{Duration, Instant}; | ||
|
||
/// Timer that combines multiple time intervals into a single measurements. | ||
/// | ||
/// The intervals are non-overlapping. Next interval can be started via [`AggregateTimer::start_interval`] | ||
#[derive(Debug)] | ||
pub struct AggregateTimer { | ||
recorded_time_secs: Duration, | ||
} | ||
|
||
impl Default for AggregateTimer { | ||
fn default() -> Self { | ||
AggregateTimer::new() | ||
} | ||
} | ||
|
||
impl AggregateTimer { | ||
pub fn new() -> Self { | ||
Self { | ||
recorded_time_secs: Duration::from_secs(0), | ||
} | ||
} | ||
|
||
pub fn start_interval(&mut self) -> Interval { | ||
Interval { | ||
start_time: Instant::now(), | ||
recorder: self, | ||
discarded: false, | ||
} | ||
} | ||
|
||
/// Add to the total | ||
pub fn add_time(&mut self, time: Duration) { | ||
self.recorded_time_secs += time; | ||
} | ||
|
||
/// Total time recorded so far | ||
pub fn total_time(&self) -> Duration { | ||
self.recorded_time_secs | ||
} | ||
} | ||
|
||
/// Timer tracking next interval. | ||
/// Records passed time when it's dropped. | ||
#[must_use = "Interval cannot record duration if it is not kept in a variable"] | ||
#[derive(Debug)] | ||
pub struct Interval<'a> { | ||
start_time: Instant, | ||
recorder: &'a mut AggregateTimer, | ||
discarded: bool, | ||
} | ||
|
||
impl<'a> Interval<'a> { | ||
/// Get current time of the interval without recording. | ||
pub fn elapsed_from_start(&self) -> Duration { | ||
self.start_time.elapsed() | ||
} | ||
|
||
/// Do not record this interval. | ||
pub fn discard(mut self) { | ||
self.discarded = true; | ||
} | ||
} | ||
|
||
impl<'a> Drop for Interval<'a> { | ||
fn drop(&mut self) { | ||
if !self.discarded { | ||
self.recorder.add_time(self.elapsed_from_start()) | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use std::thread::sleep; | ||
|
||
use super::*; | ||
|
||
#[test] | ||
fn intervals_are_approx_recorded() { | ||
let mut timer = AggregateTimer::new(); | ||
let mut total_min_time = Duration::from_secs(0); | ||
{ | ||
let time = Duration::from_secs_f64(0.1); | ||
total_min_time += time; | ||
let _interval = timer.start_interval(); | ||
sleep(time); | ||
} | ||
{ | ||
let time = Duration::from_secs_f64(0.2); | ||
total_min_time += time; | ||
let _interval = timer.start_interval(); | ||
sleep(time); | ||
} | ||
// sleep pauses for "at least the specified amount of time" | ||
assert!(timer.total_time() > total_min_time) | ||
// thus the test should be not flaky | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,5 +2,4 @@ target | |
Dockerfile | ||
README.md | ||
tests | ||
config.toml | ||
data |
Oops, something went wrong.