2023-04-12 18:33:16 +02:00
|
|
|
use crate::api::limits::{LimitType, Limits};
|
2023-04-10 17:20:02 +02:00
|
|
|
|
2023-04-12 18:33:16 +02:00
|
|
|
use reqwest::{Client, RequestBuilder, Response};
|
2023-04-07 21:51:50 +02:00
|
|
|
use std::collections::VecDeque;
|
2023-04-07 21:01:48 +02:00
|
|
|
|
2023-04-08 14:51:36 +02:00
|
|
|
// Note: There seem to be some overlapping request limiters. We need to make sure that sending a
|
|
|
|
// request checks for all the request limiters that apply, and blocks if any of the limiters are 0
|
|
|
|
|
2023-04-12 17:10:12 +02:00
|
|
|
#[allow(dead_code)]
|
2023-04-07 21:51:50 +02:00
|
|
|
pub struct LimitedRequester {
|
2023-04-07 21:01:48 +02:00
|
|
|
http: Client,
|
2023-04-12 18:33:16 +02:00
|
|
|
requests: VecDeque<RequestBuilder>,
|
2023-04-10 20:58:07 +02:00
|
|
|
last_reset_epoch: i64,
|
2023-04-12 16:49:18 +02:00
|
|
|
limits_rate: Limits,
|
2023-04-07 21:01:48 +02:00
|
|
|
}
|
|
|
|
|
2023-04-07 21:51:50 +02:00
|
|
|
impl LimitedRequester {
|
|
|
|
/// Create a new `LimitedRequester`. `LimitedRequester`s use a `VecDeque` to store requests and
|
|
|
|
/// send them to the server using a `Client`. It keeps track of the remaining requests that can
|
|
|
|
/// be send within the `Limit` of an external API Ratelimiter, and looks at the returned request
|
|
|
|
/// headers to see if it can find Ratelimit info to update itself.
|
2023-04-12 17:10:12 +02:00
|
|
|
#[allow(dead_code)]
|
2023-04-08 14:51:36 +02:00
|
|
|
pub async fn new(api_url: String) -> Self {
|
2023-04-07 21:51:50 +02:00
|
|
|
LimitedRequester {
|
2023-04-07 21:01:48 +02:00
|
|
|
http: Client::new(),
|
2023-04-07 21:51:50 +02:00
|
|
|
requests: VecDeque::new(),
|
2023-04-10 20:58:07 +02:00
|
|
|
last_reset_epoch: chrono::Utc::now().timestamp(),
|
2023-04-12 16:49:18 +02:00
|
|
|
limits_rate: Limits::check_limits(api_url).await,
|
2023-04-07 21:01:48 +02:00
|
|
|
}
|
|
|
|
}
|
2023-04-12 18:33:16 +02:00
|
|
|
|
|
|
|
fn add_to_queue(request: RequestBuilder, queue: &mut VecDeque<RequestBuilder>) {
|
|
|
|
queue.push_back(request);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn update_limits(&mut self, response: Response, limit_types: Vec<LimitType>) -> bool {
|
|
|
|
let remaining = match response.headers().get("X-RateLimit-Remaining") {
|
|
|
|
Some(remaining) => remaining,
|
|
|
|
None => return false,
|
|
|
|
};
|
|
|
|
let limit = match response.headers().get("X-RateLimit-Limit") {
|
|
|
|
Some(limit) => limit,
|
|
|
|
None => return false,
|
|
|
|
};
|
|
|
|
let reset = match response.headers().get("X-RateLimit-Reset") {
|
|
|
|
Some(reset) => reset,
|
|
|
|
None => return false,
|
|
|
|
};
|
|
|
|
}
|
2023-04-07 21:01:48 +02:00
|
|
|
}
|