use crate::models::*;
use crate::ratectl::*;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::Mutex;
use tracing::*;
#[derive(Clone, Debug)]
pub struct SlackTokioRateController {
pub config: SlackApiRateControlConfig,
throttler: Arc<Mutex<SlackRateThrottler>>,
}
impl SlackTokioRateController {
pub fn new(rate_control_config: SlackApiRateControlConfig) -> Self {
Self {
config: rate_control_config.clone(),
throttler: Arc::new(Mutex::new(SlackRateThrottler::new(rate_control_config))),
}
}
async fn calc_throttle_delay(
&self,
method_rate_ctl: Option<&SlackApiMethodRateControlConfig>,
team_id: Option<SlackTeamId>,
delayed: Option<Duration>,
) -> Option<Duration> {
let has_global_limits = self.config.global_max_rate_limit.is_some();
if has_global_limits
|| team_id.is_some()
|| method_rate_ctl
.iter()
.any(|rc| rc.special_rate_limit.is_some())
{
if let Some(exist_method_rate_ctl) = method_rate_ctl {
let mut throttler = self.throttler.lock().await;
throttler.calc_throttle_delay(exist_method_rate_ctl, team_id, delayed)
} else {
delayed
}
} else {
delayed
}
}
pub async fn throttle_delay(
&self,
method_rate_ctl: Option<&SlackApiMethodRateControlConfig>,
team_id: Option<SlackTeamId>,
delayed: Option<Duration>,
) {
if let Some(duration) = self
.calc_throttle_delay(method_rate_ctl, team_id, delayed)
.await
{
if !duration.is_zero() {
debug!("Slack throttler postponed request for {:?}", duration);
let mut interval = tokio::time::interval(duration);
interval.tick().await;
interval.tick().await;
}
}
}
}