♻️ 使用 Actix RS 重构 #8
@ -4,6 +4,7 @@ mod sideload;
|
|||||||
pub mod warden;
|
pub mod warden;
|
||||||
|
|
||||||
use actix_web::{App, HttpServer, web};
|
use actix_web::{App, HttpServer, web};
|
||||||
|
use actix_web::middleware::Logger;
|
||||||
use actix_web_httpauth::extractors::AuthenticationError;
|
use actix_web_httpauth::extractors::AuthenticationError;
|
||||||
use actix_web_httpauth::headers::www_authenticate::basic::Basic;
|
use actix_web_httpauth::headers::www_authenticate::basic::Basic;
|
||||||
use actix_web_httpauth::middleware::HttpAuthentication;
|
use actix_web_httpauth::middleware::HttpAuthentication;
|
||||||
@ -44,6 +45,7 @@ async fn main() -> Result<(), std::io::Error> {
|
|||||||
// Proxies
|
// Proxies
|
||||||
let proxies_server = HttpServer::new(|| {
|
let proxies_server = HttpServer::new(|| {
|
||||||
App::new()
|
App::new()
|
||||||
|
.wrap(Logger::default())
|
||||||
.app_data(web::Data::new(Client::default()))
|
.app_data(web::Data::new(Client::default()))
|
||||||
.route("/", web::to(route::handle))
|
.route("/", web::to(route::handle))
|
||||||
}).bind(
|
}).bind(
|
||||||
|
@ -9,12 +9,22 @@ pub struct RoadTrace {
|
|||||||
pub region: String,
|
pub region: String,
|
||||||
pub location: String,
|
pub location: String,
|
||||||
pub destination: String,
|
pub destination: String,
|
||||||
|
pub ip_address: String,
|
||||||
|
pub user_agent: String,
|
||||||
pub error: Option<String>,
|
pub error: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RoadTrace {
|
impl RoadTrace {
|
||||||
pub fn from_structs(reg: Region, loc: Location, end: Destination) -> RoadTrace {
|
pub fn from_structs(
|
||||||
|
ip: String,
|
||||||
|
ua: String,
|
||||||
|
reg: Region,
|
||||||
|
loc: Location,
|
||||||
|
end: Destination,
|
||||||
|
) -> RoadTrace {
|
||||||
RoadTrace {
|
RoadTrace {
|
||||||
|
ip_address: ip,
|
||||||
|
user_agent: ua,
|
||||||
region: reg.id,
|
region: reg.id,
|
||||||
location: loc.id,
|
location: loc.id,
|
||||||
destination: end.id,
|
destination: end.id,
|
||||||
@ -23,17 +33,16 @@ impl RoadTrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_structs_with_error(
|
pub fn from_structs_with_error(
|
||||||
|
ip: String,
|
||||||
|
ua: String,
|
||||||
reg: Region,
|
reg: Region,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
end: Destination,
|
end: Destination,
|
||||||
err: String,
|
err: String,
|
||||||
) -> RoadTrace {
|
) -> RoadTrace {
|
||||||
RoadTrace {
|
let mut trace = Self::from_structs(ip, ua, reg, loc, end);
|
||||||
region: reg.id,
|
trace.error = Some(err);
|
||||||
location: loc.id,
|
return trace;
|
||||||
destination: end.id,
|
|
||||||
error: Some(err),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +55,7 @@ pub struct RoadMetrics {
|
|||||||
pub recent_errors: VecDeque<RoadTrace>,
|
pub recent_errors: VecDeque<RoadTrace>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_TRACE_COUNT: usize = 10;
|
const MAX_TRACE_COUNT: usize = 32;
|
||||||
|
|
||||||
impl RoadMetrics {
|
impl RoadMetrics {
|
||||||
pub fn new() -> RoadMetrics {
|
pub fn new() -> RoadMetrics {
|
||||||
@ -66,26 +75,35 @@ impl RoadMetrics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_success_request(&mut self, reg: Region, loc: Location, end: Destination) {
|
pub fn add_success_request(
|
||||||
|
&mut self,
|
||||||
|
ip: String,
|
||||||
|
ua: String,
|
||||||
|
reg: Region,
|
||||||
|
loc: Location,
|
||||||
|
end: Destination,
|
||||||
|
) {
|
||||||
self.requests_count += 1;
|
self.requests_count += 1;
|
||||||
self.recent_successes
|
self.recent_successes
|
||||||
.push_back(RoadTrace::from_structs(reg, loc, end));
|
.push_back(RoadTrace::from_structs(ip, ua, reg, loc, end));
|
||||||
if self.recent_successes.len() > MAX_TRACE_COUNT {
|
if self.recent_successes.len() > MAX_TRACE_COUNT {
|
||||||
self.recent_successes.pop_front();
|
self.recent_successes.pop_front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_faliure_request(
|
pub fn add_failure_request(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
ip: String,
|
||||||
|
ua: String,
|
||||||
reg: Region,
|
reg: Region,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
end: Destination,
|
end: Destination,
|
||||||
err: String, // For some reason error is rarely clonable, so we use preformatted message
|
err: String, // For some reason error is rarely cloneable, so we use preformatted message
|
||||||
) {
|
) {
|
||||||
self.requests_count += 1;
|
self.requests_count += 1;
|
||||||
self.failures_count += 1;
|
self.failures_count += 1;
|
||||||
self.recent_errors
|
self.recent_errors
|
||||||
.push_back(RoadTrace::from_structs_with_error(reg, loc, end, err));
|
.push_back(RoadTrace::from_structs_with_error(ip, ua, reg, loc, end, err));
|
||||||
if self.recent_errors.len() > MAX_TRACE_COUNT {
|
if self.recent_errors.len() > MAX_TRACE_COUNT {
|
||||||
self.recent_errors.pop_front();
|
self.recent_errors.pop_front();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use actix_web::{HttpRequest, HttpResponse, web};
|
use actix_web::{HttpRequest, HttpResponse, web};
|
||||||
|
use actix_web::http::header;
|
||||||
use awc::Client;
|
use awc::Client;
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
|
|
||||||
@ -59,11 +60,20 @@ pub async fn handle(req: HttpRequest, client: web::Data<Client>) -> HttpResponse
|
|||||||
let loc = location.clone();
|
let loc = location.clone();
|
||||||
let end = destination.clone();
|
let end = destination.clone();
|
||||||
|
|
||||||
return match forward(&end, req, client).await {
|
let ip = match req.peer_addr() {
|
||||||
|
None => "unknown".to_string(),
|
||||||
|
Some(val) => val.ip().to_string()
|
||||||
|
};
|
||||||
|
let ua = match req.headers().get(header::USER_AGENT) {
|
||||||
|
None => "unknown".to_string(),
|
||||||
|
Some(val) => val.to_str().unwrap().to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
match forward(&end, req, client).await {
|
||||||
Ok(resp) => {
|
Ok(resp) => {
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let writable_app = &mut ROAD.lock().await;
|
let writable_app = &mut ROAD.lock().await;
|
||||||
writable_app.metrics.add_success_request(reg, loc, end);
|
writable_app.metrics.add_success_request(ip, ua, reg, loc, end);
|
||||||
});
|
});
|
||||||
resp
|
resp
|
||||||
}
|
}
|
||||||
@ -72,7 +82,7 @@ pub async fn handle(req: HttpRequest, client: web::Data<Client>) -> HttpResponse
|
|||||||
let writable_app = &mut ROAD.lock().await;
|
let writable_app = &mut ROAD.lock().await;
|
||||||
writable_app
|
writable_app
|
||||||
.metrics
|
.metrics
|
||||||
.add_faliure_request(reg, loc, end, "TODO".to_owned());
|
.add_failure_request(ip, ua, reg, loc, end, "TODO".to_owned());
|
||||||
});
|
});
|
||||||
resp
|
resp
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user