pull that resource intensive thing to another thread
This commit is contained in:
1 parent
b0cb29d911
commit
02d76d31ea
3 files changed
+84
-52
No files matched your search
@@ -0,0 +1,37 @@
|
||||
// type calparseerrtype = <Calendar as std::str::FromStr>::Err; // String
|
||||
|
||||
#[allow(nonstandard_style)]
|
||||
#[derive(Debug)]
|
||||
pub enum asspullError {
|
||||
calparse(String), // type calparseerrtype
|
||||
regexnew(fancy_regex::Error),
|
||||
}
|
||||
|
||||
// impl From<calparseerrtype> for asspullError {
|
||||
// fn from(value: calparseerrtype) -> Self {
|
||||
// asspullError::calparse(value)
|
||||
// }
|
||||
// }
|
||||
|
||||
impl From<String> for asspullError {
|
||||
fn from(value: String) -> Self {
|
||||
asspullError::calparse(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<fancy_regex::Error> for asspullError {
|
||||
fn from(value: fancy_regex::Error) -> Self {
|
||||
asspullError::regexnew(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for asspullError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
asspullError::calparse(i) => std::fmt::Display::fmt(i, f),
|
||||
asspullError::regexnew(i) => std::fmt::Display::fmt(i, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for asspullError {}
|
||||
@@ -1,3 +1,5 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use tokio::time::Instant;
|
||||
|
||||
pub struct LdaTimer<'s>{timer: Instant, message: &'s str}
|
||||
|
||||
+45
-52
@@ -6,7 +6,7 @@ use chrono::{NaiveDate, TimeDelta};
|
||||
use fancy_regex::Regex;
|
||||
use icalendar::{Calendar, CalendarComponent, Component};
|
||||
use reqwest::Client;
|
||||
mod funny_timer;
|
||||
|
||||
// use regex::Regex;
|
||||
|
||||
const ICS_URL: &str = "https://calendar.google.com/calendar/ical/i7p4ol56gi8sqe0dq7uc3m0o4c%40group.calendar.google.com/public/basic.ics";
|
||||
@@ -17,26 +17,23 @@ async fn filtered_ics(
|
||||
now: web::Data<NaiveDate>,
|
||||
query: web::Query<HashMap<String, String>>,
|
||||
) -> impl Responder {
|
||||
let cumah = funny_timer::LdaTimer::new("total time idfk");
|
||||
println!(
|
||||
"got hit from {}, path is obviously {}",
|
||||
req.peer_addr()
|
||||
.map(|s| s.to_string())
|
||||
.unwrap_or("deadass dont know".into()),
|
||||
.unwrap_or_else(|| "deadass dont know".into()),
|
||||
req.path()
|
||||
);
|
||||
let now: NaiveDate = **now;
|
||||
|
||||
let now = **now;
|
||||
let client = Client::new();
|
||||
let ics_url = query.get("url").map_or(ICS_URL, String::as_str);
|
||||
|
||||
let timer = tokio::time::Instant::now();
|
||||
// Fetch the .ics content
|
||||
let response = match client.get(ics_url).send().await {
|
||||
Ok(resp) => resp,
|
||||
Err(e) => return HttpResponse::BadGateway().body(format!("Failed to fetch ICS file: {e}")),
|
||||
};
|
||||
println!("got a response in {:?}", timer.elapsed());
|
||||
cumah.ping("function time after response");
|
||||
|
||||
let body = match response.text().await {
|
||||
Ok(text) => text,
|
||||
@@ -45,53 +42,46 @@ async fn filtered_ics(
|
||||
.body(format!("Failed to read response body: {e}"));
|
||||
}
|
||||
};
|
||||
println!("with reading file: {:?}", timer.elapsed());
|
||||
cumah.ping("function time after reading");
|
||||
|
||||
let timer = tokio::time::Instant::now();
|
||||
// Parse the .ics content
|
||||
let calendar = match body.parse::<Calendar>() {
|
||||
Ok(cal) => cal,
|
||||
Err(e) => {
|
||||
return HttpResponse::InternalServerError()
|
||||
.body(format!("Failed to parse ICS file: {e}"));
|
||||
// Compile regex
|
||||
let regex_rules = match query.get("regex") {
|
||||
Some(rule) => match Regex::new(rule) {
|
||||
Ok(reg_mc) => Some(reg_mc),
|
||||
Err(e) => return HttpResponse::BadRequest().body(format!("Invalid regex rule: {e}")),
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
// Do the CPU-heavy stuff on another thread
|
||||
let block_task = tokio::task::spawn_blocking(move || -> Result<String, String> {
|
||||
let calendar = body.parse::<Calendar>()?;
|
||||
|
||||
let start_date = now - TimeDelta::days(365);
|
||||
let end_date = now + TimeDelta::days(365);
|
||||
|
||||
let filtered_events =
|
||||
filter_events_by_date_and_regex(calendar, regex_rules, start_date, end_date);
|
||||
|
||||
let filtered_calendar = Calendar {
|
||||
components: filtered_events,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
Ok(filtered_calendar.to_string())
|
||||
});
|
||||
|
||||
// Await the result of the blocking task
|
||||
match block_task.await {
|
||||
Ok(Ok(ics_output)) => HttpResponse::Ok()
|
||||
.content_type("text/calendar")
|
||||
.body(ics_output),
|
||||
Ok(Err(e)) => {
|
||||
HttpResponse::InternalServerError().body(format!("Failed to process ICS file: {e}"))
|
||||
}
|
||||
};
|
||||
println!("parsing took {:?}", timer.elapsed());
|
||||
cumah.ping("function time after parsing");
|
||||
|
||||
let start_date = now - TimeDelta::days(365);
|
||||
let end_date = now + TimeDelta::days(365);
|
||||
|
||||
let regex_rules = query
|
||||
.get("regex")
|
||||
.and_then(|r| Regex::new(r).inspect_err(|e| eprintln!("{e}")).ok()); // silently discard a faulty regex
|
||||
// or
|
||||
// let include = query.get("").map(|c|c.split(",")); // ?
|
||||
// let exclude = query.get("").map(|c|c.split(",")); // ?
|
||||
// Filter events by summary and date range
|
||||
let timer = tokio::time::Instant::now();
|
||||
let filtered_events =
|
||||
filter_events_by_date_and_regex(calendar, regex_rules, start_date, end_date);
|
||||
println!("filtering took {:?}", timer.elapsed());
|
||||
cumah.ping("function time after filtering");
|
||||
|
||||
// Create a new calendar with filtered events
|
||||
let filtered_calendar = Calendar {
|
||||
components: filtered_events,
|
||||
..Default::default()
|
||||
};
|
||||
cumah.ping("hi");
|
||||
|
||||
// Serialize the filtered calendar
|
||||
let timer = tokio::time::Instant::now();
|
||||
let ics_output = filtered_calendar.to_string();
|
||||
println!("string building took {:?}", timer.elapsed());
|
||||
cumah.ping("function time after building the string");
|
||||
|
||||
HttpResponse::Ok()
|
||||
.content_type("text/calendar")
|
||||
.body(ics_output)
|
||||
Err(join_err) => {
|
||||
HttpResponse::InternalServerError().body(format!("Blocking thread failed: {join_err}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn filter_events_by_date_and_regex(
|
||||
@@ -153,3 +143,6 @@ async fn main() -> std::io::Result<()> {
|
||||
.run()
|
||||
.await
|
||||
}
|
||||
|
||||
mod asspull;
|
||||
mod funny_timer;
|
||||
Reference in new issue
Block a user