diff --git a/src/net/http.rs b/src/net/http.rs
index 7360ed362..0f622402e 100644
--- a/src/net/http.rs
+++ b/src/net/http.rs
@@ -151,7 +151,7 @@ async fn http_cache_put(context: &Context, url: &str, response: &Response) -> Re
/// Also returns if the response is stale and should be revalidated in the background.
async fn http_cache_get(context: &Context, url: &str) -> Result> {
let now = time();
- let Some((blob_name, mimetype, encoding, is_stale)) = context
+ let Some((blob_name, mimetype, encoding, stale_timestamp)) = context
.sql
.query_row_optional(
"SELECT blobname, mimetype, encoding, stale
@@ -162,13 +162,14 @@ async fn http_cache_get(context: &Context, url: &str) -> Result = Some(row.get(1)?).filter(|s: &String| !s.is_empty());
let encoding: Option = Some(row.get(2)?).filter(|s: &String| !s.is_empty());
let stale_timestamp: i64 = row.get(3)?;
- Ok((blob_name, mimetype, encoding, now > stale_timestamp))
+ Ok((blob_name, mimetype, encoding, stale_timestamp))
},
)
.await?
else {
return Ok(None);
};
+ let is_stale = now > stale_timestamp;
let blob_object = BlobObject::from_name(context, blob_name)?;
let blob_abs_path = blob_object.to_abs_path();
@@ -195,15 +196,16 @@ async fn http_cache_get(context: &Context, url: &str) -> Result= 1 hour,
+ // so 1 more minute won't be a problem.
+ let stale_timestamp = if is_stale { now + 60 } else { stale_timestamp };
context
.sql
.execute(
- "UPDATE http_cache SET expires=? WHERE url=?",
- (expires, url),
+ "UPDATE http_cache SET expires=?, stale=? WHERE url=?",
+ (expires, stale_timestamp, url),
)
.await?;
@@ -305,8 +307,6 @@ pub async fn read_url_blob(context: &Context, url: &str) -> Result {
}
});
}
-
- // Return stale result.
return Ok(response);
}
@@ -495,6 +495,22 @@ mod tests {
);
assert_eq!(http_cache_get(t, xdc_pixel_url).await?, None);
+ // If we get the blob the second time quickly, it shouldn't be stale because it's supposed
+ // that we've already run a revalidation task which will update the blob soon.
+ assert_eq!(
+ http_cache_get(t, xdc_editor_url).await?,
+ Some((xdc_response.clone(), false))
+ );
+ // But if the revalidation task hasn't succeeded after some time, the blob is stale again
+ // even if we continue to get it frequently.
+ for i in (0..100).rev() {
+ SystemTime::shift(Duration::from_secs(6));
+ if let Some((_, true)) = http_cache_get(t, xdc_editor_url).await? {
+ break;
+ }
+ assert!(i > 0);
+ }
+
// Test that if the file is accidentally removed from the blobdir,
// there is no error when trying to load the cache entry.
for entry in std::fs::read_dir(t.get_blobdir())? {