This commit is contained in:
Mateusz Gruszczyński committed 2026-10-31 23:42:58 +01:00
1 parent 2c03fcf248
commit d3b492874b
95 files changed
+1628 -743

No files matched your search

+22 -14
View File
@@ -735,9 +735,11 @@ mod tests {
#[test]
fn cache_preset_intent_round_trips_with_configuration() {
let mut settings = Settings::default();
settings.memory_preset = Some(MemoryPreset::Recommended);
settings.cold_preset = Some(ColdPreset::Recommended);
let settings = Settings {
memory_preset: Some(MemoryPreset::Recommended),
cold_preset: Some(ColdPreset::Recommended),
..Default::default()
};
let encoded = serde_json::to_value(&settings).unwrap();
assert_eq!(encoded["memory_preset"], "recommended");
assert_eq!(encoded["cold_preset"], "recommended");
@@ -749,9 +751,11 @@ mod tests {
#[test]
fn transient_budget_is_hard_and_released_with_lease() {
let cache = Cache::new(1);
let mut s = Settings::default();
s.transient_max_bytes = 128 * 1024;
s.cold_queue_max_bytes = 64 * 1024;
let s = Settings {
transient_max_bytes: 128 * 1024,
cold_queue_max_bytes: 64 * 1024,
..Default::default()
};
let first = cache
.try_reserve_transient(96 * 1024, &s)
.expect("first reservation");
@@ -764,20 +768,24 @@ mod tests {
#[test]
fn cold_queue_budget_cannot_exceed_transient_budget() {
let mut s = Settings::default();
s.transient_max_bytes = 8 * 1024 * 1024;
s.cold_queue_max_bytes = 16 * 1024 * 1024;
let s = Settings {
transient_max_bytes: 8 * 1024 * 1024,
cold_queue_max_bytes: 16 * 1024 * 1024,
..Default::default()
};
assert!(s.validate().is_err());
}
#[cfg(target_pointer_width = "64")]
#[test]
fn cache_limits_allow_explicit_multi_gibibyte_budgets() {
let mut s = Settings::default();
s.max_bytes = 4usize * 1024 * 1024 * 1024;
s.max_object_bytes = 2usize * 1024 * 1024 * 1024;
s.transient_max_bytes = 512usize * 1024 * 1024;
s.cold_queue_max_bytes = 256usize * 1024 * 1024;
let mut s = Settings {
max_bytes: 4usize * 1024 * 1024 * 1024,
max_object_bytes: 2usize * 1024 * 1024 * 1024,
transient_max_bytes: 512usize * 1024 * 1024,
cold_queue_max_bytes: 256usize * 1024 * 1024,
..Default::default()
};
assert!(s.validate().is_ok());
s.max_object_bytes = s.max_bytes.saturating_add(1);
assert!(s.validate().is_err());
+4 -2
View File
@@ -979,8 +979,10 @@ mod cold_tier_tests {
#[test]
fn cold_path_cannot_escape_data_directory() {
let mut settings = Settings::default();
settings.cold_path = "../outside".into();
let mut settings = Settings {
cold_path: "../outside".into(),
..Default::default()
};
assert!(settings.validate().is_err());
settings.cold_path = "/tmp/outside".into();
assert!(settings.validate().is_err());
+1 -3
View File
@@ -97,9 +97,7 @@ impl Candidate {
self.headers.insert("date", value);
}
}
for name in ["x-request-id"] {
self.headers.remove(name);
}
self.headers.remove("x-request-id");
let vary = std::mem::take(&mut self.plan.vary);
let (body, body_allocation) = if let Some(body) = self.shared.take() {
(body, self.shared_allocated)
+1 -3
View File
@@ -181,9 +181,7 @@ impl Cache {
.fetch_add(1, Ordering::Relaxed);
return None;
}
let Some(_read_lease) = self.try_reserve_transient(entry.body_bytes, settings) else {
return None;
};
let _read_lease = self.try_reserve_transient(entry.body_bytes, settings)?;
let _cold_read = ByteGaugeGuard::new(&self.cold_read_bytes_active, entry.body_bytes as u64);
let body_vec = match tokio::fs::read(&entry.body_path).await {
Ok(body) if cold_body_matches(&entry, &body) => body,
+1 -3
View File
@@ -27,9 +27,7 @@ impl Cache {
headers.insert("date", value);
}
}
for name in ["x-request-id"] {
headers.remove(name);
}
headers.remove("x-request-id");
let hits = cached.hits.saturating_add(1);
let age = plan.initial_age.as_secs();
let remaining_ttl = plan.ttl.saturating_sub(age);
+1
View File
@@ -296,6 +296,7 @@ struct ColdDraft {
_memory_lease: TransientLease,
}
#[allow(clippy::large_enum_variant)]
enum ColdCommand {
Store(ColdDraft),
Delete(Vec<PathBuf>),
+2 -2
View File
@@ -171,9 +171,9 @@ impl Revalidation {
self.reusable_without_validation
}
pub fn cache_status_forward_reason(&self, request_forces_validation: bool) -> &'static str {
if self.age >= self.ttl {
if self.age >= self.ttl || !self.reusable_without_validation {
"stale"
} else if request_forces_validation && self.reusable_without_validation {
} else if request_forces_validation {
"request"
} else {
"miss"
+2 -6
View File
@@ -48,9 +48,10 @@ fn release_allocator_memory() {
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum CollapseTimeoutFallback {
#[default]
Origin,
StaleIfAvailable,
}
@@ -63,11 +64,6 @@ pub enum StaleErrorClass {
Tls,
}
impl Default for CollapseTimeoutFallback {
fn default() -> Self {
Self::Origin
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
+5 -5
View File
@@ -3,7 +3,7 @@ fn parse_key_hex(value: &str) -> Option<Key> {
return None;
}
let mut key = [0_u8; 32];
for (index, chunk) in value.as_bytes().chunks_exact(2).enumerate() {
for (index, chunk) in value.as_bytes().as_chunks::<2>().0.iter().enumerate() {
let text = std::str::from_utf8(chunk).ok()?;
key[index] = u8::from_str_radix(text, 16).ok()?;
}
@@ -137,13 +137,13 @@ fn stale_mode(
if matches!(max_stale, Some(Some(limit)) if stale_for > limit) {
return None;
}
if max_stale.is_some() {
return Some(false);
}
if stale_while_revalidate > 0 && stale_for <= stale_while_revalidate {
return Some(true);
}
match max_stale {
Some(None) | Some(Some(_)) => Some(false),
None => None,
}
None
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+6 -4
View File
@@ -574,10 +574,12 @@ mod v022_cache_tests {
#[test]
fn stale_if_error_policy_is_configurable_by_error_class_and_status() {
let mut settings = Settings::default();
settings.stale_if_error_timeout = false;
settings.stale_if_error_dns = false;
settings.stale_if_error_statuses = vec![500, 503];
let settings = Settings {
stale_if_error_timeout: false,
stale_if_error_dns: false,
stale_if_error_statuses: vec![500, 503],
..Default::default()
};
assert!(!settings.allows_stale_error_class(StaleErrorClass::Timeout));
assert!(!settings.allows_stale_error_class(StaleErrorClass::Dns));
assert!(settings.allows_stale_error_class(StaleErrorClass::Connection));
+5 -3
View File
@@ -414,8 +414,10 @@ mod varnish_compatible_tests {
#[tokio::test]
async fn positive_fallback_ttl_reuses_only_public_no_cache_entries() {
let cache = Cache::new(1);
let mut settings = Settings::default();
settings.default_ttl_seconds = 75;
let settings = Settings {
default_ttl_seconds: 75,
..Default::default()
};
let ticket = cache
.ticket(
1,
@@ -503,7 +505,7 @@ mod varnish_compatible_tests {
)
.unwrap();
let mut response = Response::new(Body::from("css"));
*response.headers_mut() = headers("public, max-age=60");
*response.headers_mut() = headers("public, max-age=60, stale-while-revalidate=0");
let p = plan(
StatusCode::OK,
response.headers(),