Merge pull request #105 from polyphony-chat/refactor/limited-requester
Refactor/limited requester
This commit is contained in:
commit
234c0c4a8d
|
@ -15,7 +15,6 @@ impl Instance {
|
||||||
&mut self,
|
&mut self,
|
||||||
login_schema: &LoginSchema,
|
login_schema: &LoginSchema,
|
||||||
) -> Result<UserMeta, ChorusLibError> {
|
) -> Result<UserMeta, ChorusLibError> {
|
||||||
let mut requester = LimitedRequester::new().await;
|
|
||||||
let json_schema = json!(login_schema);
|
let json_schema = json!(login_schema);
|
||||||
let client = Client::new();
|
let client = Client::new();
|
||||||
let endpoint_url = self.urls.get_api().to_string() + "/auth/login";
|
let endpoint_url = self.urls.get_api().to_string() + "/auth/login";
|
||||||
|
@ -24,8 +23,7 @@ impl Instance {
|
||||||
// request (since login is an instance wide limit), which is why we are just cloning the
|
// request (since login is an instance wide limit), which is why we are just cloning the
|
||||||
// instances' limits to pass them on as user_rate_limits later.
|
// instances' limits to pass them on as user_rate_limits later.
|
||||||
let mut cloned_limits = self.limits.clone();
|
let mut cloned_limits = self.limits.clone();
|
||||||
let response = requester
|
let response = LimitedRequester::send_request(
|
||||||
.send_request(
|
|
||||||
request_builder,
|
request_builder,
|
||||||
LimitType::AuthRegister,
|
LimitType::AuthRegister,
|
||||||
&mut self.limits,
|
&mut self.limits,
|
||||||
|
|
|
@ -24,7 +24,6 @@ impl Instance {
|
||||||
register_schema: &RegisterSchema,
|
register_schema: &RegisterSchema,
|
||||||
) -> Result<UserMeta, ChorusLibError> {
|
) -> Result<UserMeta, ChorusLibError> {
|
||||||
let json_schema = json!(register_schema);
|
let json_schema = json!(register_schema);
|
||||||
let mut limited_requester = LimitedRequester::new().await;
|
|
||||||
let client = Client::new();
|
let client = Client::new();
|
||||||
let endpoint_url = self.urls.get_api().to_string() + "/auth/register";
|
let endpoint_url = self.urls.get_api().to_string() + "/auth/register";
|
||||||
let request_builder = client.post(endpoint_url).body(json_schema.to_string());
|
let request_builder = client.post(endpoint_url).body(json_schema.to_string());
|
||||||
|
@ -32,8 +31,7 @@ impl Instance {
|
||||||
// request (since register is an instance wide limit), which is why we are just cloning
|
// request (since register is an instance wide limit), which is why we are just cloning
|
||||||
// the instances' limits to pass them on as user_rate_limits later.
|
// the instances' limits to pass them on as user_rate_limits later.
|
||||||
let mut cloned_limits = self.limits.clone();
|
let mut cloned_limits = self.limits.clone();
|
||||||
let response = limited_requester
|
let response = LimitedRequester::send_request(
|
||||||
.send_request(
|
|
||||||
request_builder,
|
request_builder,
|
||||||
LimitType::AuthRegister,
|
LimitType::AuthRegister,
|
||||||
&mut self.limits,
|
&mut self.limits,
|
||||||
|
|
|
@ -5,7 +5,6 @@ use crate::{
|
||||||
api::handle_request,
|
api::handle_request,
|
||||||
errors::ChorusLibError,
|
errors::ChorusLibError,
|
||||||
instance::UserMeta,
|
instance::UserMeta,
|
||||||
limit::LimitedRequester,
|
|
||||||
types::{self, PermissionOverwrite},
|
types::{self, PermissionOverwrite},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,7 @@ pub async fn handle_request(
|
||||||
limit_type: LimitType,
|
limit_type: LimitType,
|
||||||
) -> Result<reqwest::Response, crate::errors::ChorusLibError> {
|
) -> Result<reqwest::Response, crate::errors::ChorusLibError> {
|
||||||
let mut belongs_to = user.belongs_to.borrow_mut();
|
let mut belongs_to = user.belongs_to.borrow_mut();
|
||||||
match LimitedRequester::new()
|
match LimitedRequester::send_request(
|
||||||
.await
|
|
||||||
.send_request(
|
|
||||||
request,
|
request,
|
||||||
limit_type,
|
limit_type,
|
||||||
&mut belongs_to.limits,
|
&mut belongs_to.limits,
|
||||||
|
|
|
@ -180,9 +180,7 @@ impl Guild {
|
||||||
let request = Client::new()
|
let request = Client::new()
|
||||||
.get(format!("{}/guilds/{}/", url_api, guild_id))
|
.get(format!("{}/guilds/{}/", url_api, guild_id))
|
||||||
.bearer_auth(token);
|
.bearer_auth(token);
|
||||||
let response = match LimitedRequester::new()
|
let response = match LimitedRequester::send_request(
|
||||||
.await
|
|
||||||
.send_request(
|
|
||||||
request,
|
request,
|
||||||
crate::api::limits::LimitType::Guild,
|
crate::api::limits::LimitType::Guild,
|
||||||
limits_instance,
|
limits_instance,
|
||||||
|
@ -242,9 +240,7 @@ impl Channel {
|
||||||
.post(format!("{}/guilds/{}/channels/", url_api, guild_id))
|
.post(format!("{}/guilds/{}/channels/", url_api, guild_id))
|
||||||
.bearer_auth(token)
|
.bearer_auth(token)
|
||||||
.body(to_string(&schema).unwrap());
|
.body(to_string(&schema).unwrap());
|
||||||
let mut requester = LimitedRequester::new().await;
|
let result = match LimitedRequester::send_request(
|
||||||
let result = match requester
|
|
||||||
.send_request(
|
|
||||||
request,
|
request,
|
||||||
crate::api::limits::LimitType::Guild,
|
crate::api::limits::LimitType::Guild,
|
||||||
limits_instance,
|
limits_instance,
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use serde_json::from_str;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api::{deserialize_response, handle_request_as_option},
|
api::{deserialize_response, handle_request_as_option},
|
||||||
errors::ChorusLibError,
|
errors::ChorusLibError,
|
||||||
instance::UserMeta,
|
instance::UserMeta,
|
||||||
limit::LimitedRequester,
|
|
||||||
types,
|
types,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use serde_json::{from_str, to_string};
|
use serde_json::to_string;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api::deserialize_response,
|
api::deserialize_response,
|
||||||
errors::ChorusLibError,
|
errors::ChorusLibError,
|
||||||
instance::UserMeta,
|
instance::UserMeta,
|
||||||
limit::LimitedRequester,
|
|
||||||
types::{self, RoleCreateModifySchema, RoleObject},
|
types::{self, RoleCreateModifySchema, RoleObject},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use serde_json::{from_str, to_string};
|
use serde_json::to_string;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api::{deserialize_response, handle_request_as_option, limits::Limits},
|
api::{deserialize_response, handle_request_as_option, limits::Limits},
|
||||||
|
@ -110,10 +110,8 @@ impl User {
|
||||||
url = format!("{}/users/{}", url_api, id.unwrap());
|
url = format!("{}/users/{}", url_api, id.unwrap());
|
||||||
}
|
}
|
||||||
let request = reqwest::Client::new().get(url).bearer_auth(token);
|
let request = reqwest::Client::new().get(url).bearer_auth(token);
|
||||||
let mut requester = crate::limit::LimitedRequester::new().await;
|
|
||||||
let mut cloned_limits = limits_instance.clone();
|
let mut cloned_limits = limits_instance.clone();
|
||||||
match requester
|
match LimitedRequester::send_request(
|
||||||
.send_request(
|
|
||||||
request,
|
request,
|
||||||
crate::api::limits::LimitType::Ip,
|
crate::api::limits::LimitType::Ip,
|
||||||
limits_instance,
|
limits_instance,
|
||||||
|
@ -138,9 +136,7 @@ impl User {
|
||||||
.get(format!("{}/users/@me/settings/", url_api))
|
.get(format!("{}/users/@me/settings/", url_api))
|
||||||
.bearer_auth(token);
|
.bearer_auth(token);
|
||||||
let mut cloned_limits = instance_limits.clone();
|
let mut cloned_limits = instance_limits.clone();
|
||||||
let mut requester = crate::limit::LimitedRequester::new().await;
|
match LimitedRequester::send_request(
|
||||||
match requester
|
|
||||||
.send_request(
|
|
||||||
request,
|
request,
|
||||||
crate::api::limits::LimitType::Ip,
|
crate::api::limits::LimitType::Ip,
|
||||||
instance_limits,
|
instance_limits,
|
||||||
|
|
55
src/limit.rs
55
src/limit.rs
|
@ -1,5 +1,3 @@
|
||||||
use std::collections::VecDeque;
|
|
||||||
|
|
||||||
use reqwest::{Client, RequestBuilder, Response};
|
use reqwest::{Client, RequestBuilder, Response};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -18,24 +16,9 @@ pub struct TypedRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct LimitedRequester {
|
pub struct LimitedRequester;
|
||||||
http: Client,
|
|
||||||
requests: VecDeque<TypedRequest>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LimitedRequester {
|
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.
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub async fn new() -> Self {
|
|
||||||
LimitedRequester {
|
|
||||||
http: Client::new(),
|
|
||||||
requests: VecDeque::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
# send_request
|
# send_request
|
||||||
Checks, if a request can be sent without hitting API rate limits and sends it, if true.
|
Checks, if a request can be sent without hitting API rate limits and sends it, if true.
|
||||||
|
@ -67,13 +50,12 @@ impl LimitedRequester {
|
||||||
methods' Errors section for more information.
|
methods' Errors section for more information.
|
||||||
*/
|
*/
|
||||||
pub async fn send_request(
|
pub async fn send_request(
|
||||||
&mut self,
|
|
||||||
request: RequestBuilder,
|
request: RequestBuilder,
|
||||||
limit_type: LimitType,
|
limit_type: LimitType,
|
||||||
instance_rate_limits: &mut Limits,
|
instance_rate_limits: &mut Limits,
|
||||||
user_rate_limits: &mut Limits,
|
user_rate_limits: &mut Limits,
|
||||||
) -> Result<Response, ChorusLibError> {
|
) -> Result<Response, ChorusLibError> {
|
||||||
if self.can_send_request(limit_type, instance_rate_limits, user_rate_limits) {
|
if LimitedRequester::can_send_request(limit_type, instance_rate_limits, user_rate_limits) {
|
||||||
let built_request = match request.build() {
|
let built_request = match request.build() {
|
||||||
Ok(request) => request,
|
Ok(request) => request,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -83,7 +65,7 @@ impl LimitedRequester {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let result = self.http.execute(built_request).await;
|
let result = Client::new().execute(built_request).await;
|
||||||
let response = match result {
|
let response = match result {
|
||||||
Ok(is_response) => is_response,
|
Ok(is_response) => is_response,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -92,7 +74,7 @@ impl LimitedRequester {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.update_limits(
|
LimitedRequester::update_limits(
|
||||||
&response,
|
&response,
|
||||||
limit_type,
|
limit_type,
|
||||||
instance_rate_limits,
|
instance_rate_limits,
|
||||||
|
@ -112,10 +94,6 @@ impl LimitedRequester {
|
||||||
Ok(response)
|
Ok(response)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.requests.push_back(TypedRequest {
|
|
||||||
request,
|
|
||||||
limit_type,
|
|
||||||
});
|
|
||||||
Err(ChorusLibError::RateLimited {
|
Err(ChorusLibError::RateLimited {
|
||||||
bucket: limit_type.to_string(),
|
bucket: limit_type.to_string(),
|
||||||
})
|
})
|
||||||
|
@ -134,7 +112,6 @@ impl LimitedRequester {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn can_send_request(
|
fn can_send_request(
|
||||||
&mut self,
|
|
||||||
limit_type: LimitType,
|
limit_type: LimitType,
|
||||||
instance_rate_limits: &Limits,
|
instance_rate_limits: &Limits,
|
||||||
user_rate_limits: &Limits,
|
user_rate_limits: &Limits,
|
||||||
|
@ -185,7 +162,6 @@ impl LimitedRequester {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_limits(
|
fn update_limits(
|
||||||
&mut self,
|
|
||||||
response: &Response,
|
response: &Response,
|
||||||
limit_type: LimitType,
|
limit_type: LimitType,
|
||||||
instance_rate_limits: &mut Limits,
|
instance_rate_limits: &mut Limits,
|
||||||
|
@ -286,16 +262,6 @@ mod rate_limit {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn create_limited_requester() {
|
|
||||||
let _urls = URLBundle::new(
|
|
||||||
String::from("http://localhost:3001/api/"),
|
|
||||||
String::from("wss://localhost:3001/"),
|
|
||||||
String::from("http://localhost:3001/cdn"),
|
|
||||||
);
|
|
||||||
let _requester = LimitedRequester::new().await;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn run_into_limit() {
|
async fn run_into_limit() {
|
||||||
let urls = URLBundle::new(
|
let urls = URLBundle::new(
|
||||||
|
@ -303,17 +269,15 @@ mod rate_limit {
|
||||||
String::from("wss://localhost:3001/"),
|
String::from("wss://localhost:3001/"),
|
||||||
String::from("http://localhost:3001/cdn"),
|
String::from("http://localhost:3001/cdn"),
|
||||||
);
|
);
|
||||||
let mut requester = LimitedRequester::new().await;
|
|
||||||
let mut request: Option<Result<Response, ChorusLibError>> = None;
|
let mut request: Option<Result<Response, ChorusLibError>> = None;
|
||||||
let mut instance_rate_limits = Limits::check_limits(urls.api.clone()).await;
|
let mut instance_rate_limits = Limits::check_limits(urls.api.clone()).await;
|
||||||
let mut user_rate_limits = Limits::check_limits(urls.api.clone()).await;
|
let mut user_rate_limits = Limits::check_limits(urls.api.clone()).await;
|
||||||
|
|
||||||
for _ in 0..=50 {
|
for _ in 0..=50 {
|
||||||
let request_path = urls.api.clone() + "/some/random/nonexisting/path";
|
let request_path = urls.api.clone() + "/some/random/nonexisting/path";
|
||||||
let request_builder = requester.http.get(request_path);
|
let request_builder = Client::new().get(request_path);
|
||||||
request = Some(
|
request = Some(
|
||||||
requester
|
LimitedRequester::send_request(
|
||||||
.send_request(
|
|
||||||
request_builder,
|
request_builder,
|
||||||
LimitType::Channel,
|
LimitType::Channel,
|
||||||
&mut instance_rate_limits,
|
&mut instance_rate_limits,
|
||||||
|
@ -341,11 +305,10 @@ mod rate_limit {
|
||||||
);
|
);
|
||||||
let mut instance_rate_limits = Limits::check_limits(urls.api.clone()).await;
|
let mut instance_rate_limits = Limits::check_limits(urls.api.clone()).await;
|
||||||
let mut user_rate_limits = Limits::check_limits(urls.api.clone()).await;
|
let mut user_rate_limits = Limits::check_limits(urls.api.clone()).await;
|
||||||
let mut requester = LimitedRequester::new().await;
|
let _requester = LimitedRequester;
|
||||||
let request_path = urls.api.clone() + "/policies/instance/limits";
|
let request_path = urls.api.clone() + "/policies/instance/limits";
|
||||||
let request_builder = requester.http.get(request_path);
|
let request_builder = Client::new().get(request_path);
|
||||||
let request = requester
|
let request = LimitedRequester::send_request(
|
||||||
.send_request(
|
|
||||||
request_builder,
|
request_builder,
|
||||||
LimitType::Channel,
|
LimitType::Channel,
|
||||||
&mut instance_rate_limits,
|
&mut instance_rate_limits,
|
||||||
|
|
Loading…
Reference in New Issue