Spencerjibz commited on
Commit
6b9469e
1 Parent(s): f5cf5f9

cache the next, current and previous results in a separate task

Browse files
Files changed (1) hide show
  1. src/server/routes/search.rs +56 -13
src/server/routes/search.rs CHANGED
@@ -40,6 +40,7 @@ pub async fn search(
40
  config: web::Data<Config>,
41
  cache: web::Data<SharedCache>,
42
  ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
 
43
  let params = web::Query::<SearchParams>::from_query(req.query_string())?;
44
  match &params.q {
45
  Some(query) => {
@@ -79,12 +80,50 @@ pub async fn search(
79
 
80
  // .max(1) makes sure that the page >= 0.
81
  let page = params.page.unwrap_or(1).max(1) - 1;
 
 
82
 
83
- let (_, results, _) = join!(
84
- get_results(page.saturating_sub(1)),
85
- get_results(page),
86
- get_results(page + 1)
87
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
  Ok(HttpResponse::Ok().content_type(ContentType::html()).body(
90
  crate::templates::views::search::search(
@@ -92,7 +131,7 @@ pub async fn search(
92
  &config.style.theme,
93
  &config.style.animation,
94
  query,
95
- &results?,
96
  )
97
  .0,
98
  ))
@@ -124,7 +163,7 @@ async fn results(
124
  query: &str,
125
  page: u32,
126
  search_settings: &server_models::Cookie<'_>,
127
- ) -> Result<SearchResults, Box<dyn std::error::Error>> {
128
  // eagerly parse cookie value to evaluate safe search level
129
  let safe_search_level = search_settings.safe_search_level;
130
 
@@ -143,7 +182,7 @@ async fn results(
143
  // check if fetched cache results was indeed fetched or it was an error and if so
144
  // handle the data accordingly.
145
  match cached_results {
146
- Ok(results) => Ok(results),
147
  Err(_) => {
148
  if safe_search_level == 4 {
149
  let mut results: SearchResults = SearchResults::default();
@@ -153,9 +192,11 @@ async fn results(
153
  // Return early when query contains disallowed words,
154
  if flag {
155
  results.set_disallowed();
156
- cache.cache_results(&results, &cache_key).await?;
 
 
157
  results.set_safe_search_level(safe_search_level);
158
- return Ok(results);
159
  }
160
  }
161
 
@@ -173,7 +214,7 @@ async fn results(
173
  &search_settings
174
  .engines
175
  .iter()
176
- .filter_map(|engine| EngineHandler::new(&engine).ok())
177
  .collect::<Vec<EngineHandler>>(),
178
  config.request_timeout,
179
  safe_search_level,
@@ -192,9 +233,11 @@ async fn results(
192
  {
193
  results.set_filtered();
194
  }
195
- cache.cache_results(&results, &cache_key).await?;
 
 
196
  results.set_safe_search_level(safe_search_level);
197
- Ok(results)
198
  }
199
  }
200
  }
 
40
  config: web::Data<Config>,
41
  cache: web::Data<SharedCache>,
42
  ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
43
+ use std::sync::Arc;
44
  let params = web::Query::<SearchParams>::from_query(req.query_string())?;
45
  match &params.q {
46
  Some(query) => {
 
80
 
81
  // .max(1) makes sure that the page >= 0.
82
  let page = params.page.unwrap_or(1).max(1) - 1;
83
+ let previous_page = page.saturating_sub(1);
84
+ let next_page = page + 1;
85
 
86
+ let mut results = Arc::new((SearchResults::default(), String::default()));
87
+ if page != previous_page {
88
+ let (previous_results, current_results, next_results) = join!(
89
+ get_results(previous_page),
90
+ get_results(page),
91
+ get_results(next_page)
92
+ );
93
+ let (parsed_previous_results, parsed_next_results) =
94
+ (previous_results?, next_results?);
95
+
96
+ let (cache_keys, results_list) = (
97
+ [
98
+ parsed_previous_results.1,
99
+ results.1.clone(),
100
+ parsed_next_results.1,
101
+ ],
102
+ [
103
+ parsed_previous_results.0,
104
+ results.0.clone(),
105
+ parsed_next_results.0,
106
+ ],
107
+ );
108
+
109
+ results = Arc::new(current_results?);
110
+
111
+ tokio::spawn(async move { cache.cache_results(&results_list, &cache_keys).await });
112
+ } else {
113
+ let (current_results, next_results) =
114
+ join!(get_results(page), get_results(page + 1));
115
+
116
+ let parsed_next_results = next_results?;
117
+
118
+ results = Arc::new(current_results?);
119
+
120
+ let (cache_keys, results_list) = (
121
+ [results.1.clone(), parsed_next_results.1.clone()],
122
+ [results.0.clone(), parsed_next_results.0],
123
+ );
124
+
125
+ tokio::spawn(async move { cache.cache_results(&results_list, &cache_keys).await });
126
+ }
127
 
128
  Ok(HttpResponse::Ok().content_type(ContentType::html()).body(
129
  crate::templates::views::search::search(
 
131
  &config.style.theme,
132
  &config.style.animation,
133
  query,
134
+ &results.0,
135
  )
136
  .0,
137
  ))
 
163
  query: &str,
164
  page: u32,
165
  search_settings: &server_models::Cookie<'_>,
166
+ ) -> Result<(SearchResults, String), Box<dyn std::error::Error>> {
167
  // eagerly parse cookie value to evaluate safe search level
168
  let safe_search_level = search_settings.safe_search_level;
169
 
 
182
  // check if fetched cache results was indeed fetched or it was an error and if so
183
  // handle the data accordingly.
184
  match cached_results {
185
+ Ok(results) => Ok((results, cache_key)),
186
  Err(_) => {
187
  if safe_search_level == 4 {
188
  let mut results: SearchResults = SearchResults::default();
 
192
  // Return early when query contains disallowed words,
193
  if flag {
194
  results.set_disallowed();
195
+ cache
196
+ .cache_results(&[results.clone()], &[cache_key.clone()])
197
+ .await?;
198
  results.set_safe_search_level(safe_search_level);
199
+ return Ok((results, cache_key));
200
  }
201
  }
202
 
 
214
  &search_settings
215
  .engines
216
  .iter()
217
+ .filter_map(|engine| EngineHandler::new(engine).ok())
218
  .collect::<Vec<EngineHandler>>(),
219
  config.request_timeout,
220
  safe_search_level,
 
233
  {
234
  results.set_filtered();
235
  }
236
+ cache
237
+ .cache_results(&[results.clone()], &[cache_key.clone()])
238
+ .await?;
239
  results.set_safe_search_level(safe_search_level);
240
+ Ok((results, cache_key))
241
  }
242
  }
243
  }