Merge pull request 'Enh RateLimiters with Async Sleep' (#25) from chat_async_sleep into main
All checks were successful
ci/woodpecker/push/cargo-checks Pipeline was successful
All checks were successful
ci/woodpecker/push/cargo-checks Pipeline was successful
Reviewed-on: #25
This commit is contained in:
commit
53c5780322
3 changed files with 50 additions and 6 deletions
|
@ -19,6 +19,8 @@ use crate::core::botinstance::ChType;
|
|||
use crate::core::botlog;
|
||||
pub use ChType::Channel;
|
||||
|
||||
use tokio::time::{sleep, Duration};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Chat {
|
||||
pub ratelimiters: Arc<Mutex<HashMap<ChType, RateLimiter>>>, // used to limit messages sent per channel
|
||||
|
@ -59,6 +61,11 @@ impl Chat {
|
|||
.get_mut(&Channel(String::from(&msg.channel_login)))
|
||||
.expect("ERROR: Issue with Rate limiters");
|
||||
|
||||
// Continue to check the limiter and sleep if required if the minimum is not reached
|
||||
while let ratelimiter::LimiterResp::Sleep(sleeptime) = contextratelimiter.check_limiter() {
|
||||
sleep(Duration::from_secs_f64(sleeptime)).await;
|
||||
}
|
||||
|
||||
match contextratelimiter.check_limiter() {
|
||||
ratelimiter::LimiterResp::Allow => {
|
||||
let maxblanks = rand::thread_rng().gen_range(1..=20);
|
||||
|
@ -73,8 +80,8 @@ impl Chat {
|
|||
contextratelimiter.increment_counter();
|
||||
|
||||
let logstr = format!(
|
||||
"(#{}) > {} ; Ratelimiers : {:?}",
|
||||
msg.channel_login, "rate limit counter increase", self.ratelimiters
|
||||
"(#{}) > {} ; contextratelimiter : {:?}",
|
||||
msg.channel_login, "rate limit counter increase", contextratelimiter
|
||||
);
|
||||
|
||||
botlog::trace(
|
||||
|
@ -86,7 +93,11 @@ impl Chat {
|
|||
ratelimiter::LimiterResp::Skip => {
|
||||
// (); // do nothing otherwise
|
||||
}
|
||||
ratelimiter::LimiterResp::Sleep(_) => {
|
||||
panic!("ISSUE : sleep was already awaited - Should not happen?");
|
||||
}
|
||||
}
|
||||
|
||||
Log::flush();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,23 @@
|
|||
const TIME_THRESHOLD_S: u64 = 30;
|
||||
const TIME_MIN_S_F64: f64 = 1.0;
|
||||
const MSG_THRESHOLD: u32 = 20;
|
||||
|
||||
use std::time::Instant;
|
||||
use crate::core::botlog;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RateLimiter {
|
||||
timer: Instant,
|
||||
msgcounter: u32,
|
||||
lastmsgtimer : Instant,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum LimiterResp {
|
||||
Allow, // when it's evaluated to be within limits
|
||||
Skip, // as outside of rate limits
|
||||
// Enqueue, // [FUTURE]
|
||||
Sleep(f64), // Sleep for x seconds
|
||||
}
|
||||
|
||||
impl Default for RateLimiter {
|
||||
|
@ -26,23 +31,50 @@ impl RateLimiter {
|
|||
Self {
|
||||
timer: Instant::now(),
|
||||
msgcounter: 0,
|
||||
lastmsgtimer: Instant::now(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_limiter(&mut self) -> LimiterResp {
|
||||
if self.timer.elapsed().as_secs() >= TIME_THRESHOLD_S {
|
||||
|
||||
|
||||
let logstr = format!(
|
||||
">> RateLimiter > {:?}",self
|
||||
);
|
||||
|
||||
botlog::trace(
|
||||
logstr.as_str(),
|
||||
Some("Rate Limiter Inner".to_string()),
|
||||
None,
|
||||
);
|
||||
|
||||
|
||||
let rsp = if self.timer.elapsed().as_secs() >= TIME_THRESHOLD_S {
|
||||
self.timer = Instant::now();
|
||||
self.msgcounter = 0;
|
||||
LimiterResp::Allow
|
||||
} else if self.msgcounter < MSG_THRESHOLD {
|
||||
} else if self.msgcounter < MSG_THRESHOLD &&
|
||||
self.lastmsgtimer.elapsed().as_secs_f64() >= TIME_MIN_S_F64 {
|
||||
LimiterResp::Allow
|
||||
} else {
|
||||
// when elapsed() < TIME_THRESHOLD_S && msgcounter >= MSG_THRESHOLD
|
||||
LimiterResp::Skip
|
||||
}
|
||||
// LimiterResp::Skip
|
||||
LimiterResp::Sleep(TIME_MIN_S_F64 - self.lastmsgtimer.elapsed().as_secs_f64())
|
||||
};
|
||||
|
||||
botlog::trace(
|
||||
&format!("Limiter Response : {:?} ; Elapsed (as_sec_f64) : {}",
|
||||
rsp, self.lastmsgtimer.elapsed().as_secs_f64()),
|
||||
Some("Rate Limiter Inner".to_string()),
|
||||
None,
|
||||
);
|
||||
|
||||
rsp
|
||||
|
||||
}
|
||||
|
||||
pub fn increment_counter(&mut self) {
|
||||
self.msgcounter += 1;
|
||||
self.lastmsgtimer = Instant::now();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ async fn good_girl(bot: BotAR, msg: PrivmsgMessage) {
|
|||
|
||||
if msg.sender.name.to_lowercase() == "ModulatingForce".to_lowercase()
|
||||
|| msg.sender.name.to_lowercase() == "mzNToRi".to_lowercase()
|
||||
// if msg.sender.name.to_lowercase() == "mzNToRi".to_lowercase()
|
||||
{
|
||||
botlog::debug(
|
||||
"Good Girl Detected > Pausechamp",
|
||||
|
|
Loading…
Reference in a new issue