add simple rate-counter

This commit is contained in:
Bryan Stitt 2023-02-25 14:40:22 -08:00
parent c9e5661c5b
commit 28ac542bc9
4 changed files with 53 additions and 0 deletions

8
Cargo.lock generated

@ -3726,6 +3726,14 @@ dependencies = [
"rand_core",
]
[[package]]
name = "rate-counter"
version = "0.1.0"
dependencies = [
"flume",
"tokio",
]
[[package]]
name = "rayon"
version = "1.6.1"

@ -3,6 +3,7 @@ members = [
"deferred-rate-limiter",
"entities",
"migration",
"rate-counter",
"redis-rate-limiter",
"thread-fast-rng",
"web3_proxy",

9
rate-counter/Cargo.toml Normal file

@ -0,0 +1,9 @@
[package]
name = "rate-counter"
version = "0.1.0"
authors = ["Bryan Stitt <bryan@llamanodes.com>"]
edition = "2021"
[dependencies]
flume = "0.10.14"
tokio = { version = "1.25.0", features = ["time"] }

35
rate-counter/src/lib.rs Normal file

@ -0,0 +1,35 @@
//! A counter of events in a time period.
use std::collections::VecDeque;
use tokio::time::{Duration, Instant};
/// Measures ticks in a time period.
#[derive(Debug)]
pub struct RateCounter {
period: Duration,
items: VecDeque<Instant>,
}
impl RateCounter {
pub fn new(period: Duration) -> Self {
let items = VecDeque::new();
Self { period, items }
}
/// update the counter and return the rate for the current period
/// true if the current time should be counted
pub fn update(&mut self, tick: bool) -> usize {
let now = Instant::now();
let too_old = now - self.period;
while self.items.front().map_or(false, |t| *t < too_old) {
self.items.pop_front();
}
if tick {
self.items.push_back(now);
}
self.items.len()
}
}