0
0
mirror of https://github.com/neon-mmd/websurfx.git synced 2024-11-21 13:38:21 -05:00

🐛 fix: reimplement caching code within the search function (#592)

- reduce resource usage &
- only cache search results which has not been cached before.
This commit is contained in:
neon_arch 2024-09-02 21:10:54 +05:30
parent ebee1f4a6c
commit 9a5f1c5f44

View File

@ -12,6 +12,7 @@ use crate::{
results::aggregator::aggregate, results::aggregator::aggregate,
}; };
use actix_web::{get, http::header::ContentType, web, HttpRequest, HttpResponse}; use actix_web::{get, http::header::ContentType, web, HttpRequest, HttpResponse};
use itertools::Itertools;
use regex::Regex; use regex::Regex;
use std::borrow::Cow; use std::borrow::Cow;
use tokio::{ use tokio::{
@ -40,7 +41,6 @@ pub async fn search(
config: web::Data<&'static Config>, config: web::Data<&'static Config>,
cache: web::Data<&'static SharedCache>, cache: web::Data<&'static SharedCache>,
) -> Result<HttpResponse, Box<dyn std::error::Error>> { ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
use std::sync::Arc;
let params = web::Query::<SearchParams>::from_query(req.query_string())?; let params = web::Query::<SearchParams>::from_query(req.query_string())?;
match &params.q { match &params.q {
Some(query) => { Some(query) => {
@ -83,44 +83,36 @@ pub async fn search(
let previous_page = page.saturating_sub(1); let previous_page = page.saturating_sub(1);
let next_page = page + 1; let next_page = page + 1;
let mut results = Arc::new((SearchResults::default(), String::default())); let results: (SearchResults, String, bool);
if page != previous_page { if page != previous_page {
let (previous_results, current_results, next_results) = join!( let (previous_results, current_results, next_results) = join!(
get_results(previous_page), get_results(previous_page),
get_results(page), get_results(page),
get_results(next_page) get_results(next_page)
); );
let (parsed_previous_results, parsed_next_results) =
(previous_results?, next_results?);
let (cache_keys, results_list) = ( results = current_results?;
[
parsed_previous_results.1,
results.1.clone(),
parsed_next_results.1,
],
[
parsed_previous_results.0,
results.0.clone(),
parsed_next_results.0,
],
);
results = Arc::new(current_results?); let (results_list, cache_keys): (Vec<SearchResults>, Vec<String>) =
[previous_results?, results.clone(), next_results?]
.into_iter()
.filter_map(|(result, cache_key, flag)| {
dbg!(flag).then_some((result, cache_key))
})
.multiunzip();
tokio::spawn(async move { cache.cache_results(&results_list, &cache_keys).await }); tokio::spawn(async move { cache.cache_results(&results_list, &cache_keys).await });
} else { } else {
let (current_results, next_results) = let (current_results, next_results) =
join!(get_results(page), get_results(page + 1)); join!(get_results(page), get_results(page + 1));
let parsed_next_results = next_results?; results = current_results?;
results = Arc::new(current_results?); let (results_list, cache_keys): (Vec<SearchResults>, Vec<String>) =
[results.clone(), next_results?]
let (cache_keys, results_list) = ( .into_iter()
[results.1.clone(), parsed_next_results.1.clone()], .filter_map(|(result, cache_key, flag)| flag.then_some((result, cache_key)))
[results.0.clone(), parsed_next_results.0], .multiunzip();
);
tokio::spawn(async move { cache.cache_results(&results_list, &cache_keys).await }); tokio::spawn(async move { cache.cache_results(&results_list, &cache_keys).await });
} }
@ -163,7 +155,7 @@ async fn results(
query: &str, query: &str,
page: u32, page: u32,
search_settings: &server_models::Cookie<'_>, search_settings: &server_models::Cookie<'_>,
) -> Result<(SearchResults, String), Box<dyn std::error::Error>> { ) -> Result<(SearchResults, String, bool), Box<dyn std::error::Error>> {
// eagerly parse cookie value to evaluate safe search level // eagerly parse cookie value to evaluate safe search level
let safe_search_level = search_settings.safe_search_level; let safe_search_level = search_settings.safe_search_level;
@ -182,7 +174,7 @@ async fn results(
// check if fetched cache results was indeed fetched or it was an error and if so // check if fetched cache results was indeed fetched or it was an error and if so
// handle the data accordingly. // handle the data accordingly.
match cached_results { match cached_results {
Ok(results) => Ok((results, cache_key)), Ok(results) => Ok((results, cache_key, false)),
Err(_) => { Err(_) => {
if safe_search_level == 4 { if safe_search_level == 4 {
let mut results: SearchResults = SearchResults::default(); let mut results: SearchResults = SearchResults::default();
@ -196,7 +188,7 @@ async fn results(
.cache_results(&[results.clone()], &[cache_key.clone()]) .cache_results(&[results.clone()], &[cache_key.clone()])
.await?; .await?;
results.set_safe_search_level(safe_search_level); results.set_safe_search_level(safe_search_level);
return Ok((results, cache_key)); return Ok((results, cache_key, true));
} }
} }
@ -235,7 +227,7 @@ async fn results(
.cache_results(&[results.clone()], &[cache_key.clone()]) .cache_results(&[results.clone()], &[cache_key.clone()])
.await?; .await?;
results.set_safe_search_level(safe_search_level); results.set_safe_search_level(safe_search_level);
Ok((results, cache_key)) Ok((results, cache_key, true))
} }
} }
} }