0.34.6_repo_cleanup
This commit is contained in:
1 parent
ce1a90397c
commit
133d2f0f91
273 files changed
+5969
-6926
No files matched your search
Vendored
+36
-41
@@ -111,7 +111,9 @@ impl Cache {
|
||||
let weak = Arc::downgrade(&cache);
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
let Some(cache) = weak.upgrade() else { break; };
|
||||
let Some(cache) = weak.upgrade() else {
|
||||
break;
|
||||
};
|
||||
let interval = cache
|
||||
.tier_settings
|
||||
.lock()
|
||||
@@ -130,9 +132,6 @@ impl Cache {
|
||||
cache
|
||||
}
|
||||
fn fill_headroom_bytes(max_bytes: usize) -> usize {
|
||||
// Allocation rounding is allowed a small global cushion, never a whole
|
||||
// max_object allocation. Use roughly 1/64 of HOT, cap it at 1 MiB and
|
||||
// never let the cushion itself exceed 1/8 of a very small HOT budget.
|
||||
let proportional = (max_bytes / 64).clamp(4 * 1024, 1024 * 1024);
|
||||
proportional.min((max_bytes / 8).max(1))
|
||||
}
|
||||
@@ -164,17 +163,14 @@ impl Cache {
|
||||
}
|
||||
}
|
||||
|
||||
/// Reserve real allocation for an in-progress fill before growing its buffer.
|
||||
/// Existing HOT objects are LRU-evicted/demoted first so HOT + active fill
|
||||
/// allocation cannot race arbitrarily above the configured HOT budget.
|
||||
fn reserve_fill_allocation(&self, bytes: usize, settings: &Settings) -> Option<TransientLease> {
|
||||
if bytes == 0 {
|
||||
return self.try_reserve_transient(0, settings);
|
||||
}
|
||||
let lease = self.try_reserve_transient(bytes, settings)?;
|
||||
let mut store = self.store.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let fill_now = usize::try_from(self.fill_bytes_active.load(Ordering::Relaxed))
|
||||
.unwrap_or(usize::MAX);
|
||||
let fill_now =
|
||||
usize::try_from(self.fill_bytes_active.load(Ordering::Relaxed)).unwrap_or(usize::MAX);
|
||||
let allowed = settings
|
||||
.max_bytes
|
||||
.saturating_add(Self::fill_headroom_bytes(settings.max_bytes));
|
||||
@@ -182,20 +178,14 @@ impl Cache {
|
||||
let generation = store.generation;
|
||||
let mut removed = 0usize;
|
||||
let mut released_hot = false;
|
||||
while store
|
||||
.bytes
|
||||
.saturating_add(fill_now)
|
||||
.saturating_add(bytes)
|
||||
> allowed
|
||||
{
|
||||
while store.bytes.saturating_add(fill_now).saturating_add(bytes) > allowed {
|
||||
if removed >= settings.hot_eviction_max_objects {
|
||||
self.counters
|
||||
.hot_eviction_limited
|
||||
.fetch_add(1, Ordering::Relaxed);
|
||||
break;
|
||||
}
|
||||
let Some((_, key)) = store.lru.first_key_value().map(|(seq, key)| (*seq, *key))
|
||||
else {
|
||||
let Some((_, key)) = store.lru.first_key_value().map(|(seq, key)| (*seq, *key)) else {
|
||||
break;
|
||||
};
|
||||
let Some(old) = store.remove(&key) else {
|
||||
@@ -227,11 +217,7 @@ impl Cache {
|
||||
self.counters.evictions.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
let fits = store
|
||||
.bytes
|
||||
.saturating_add(fill_now)
|
||||
.saturating_add(bytes)
|
||||
<= allowed;
|
||||
let fits = store.bytes.saturating_add(fill_now).saturating_add(bytes) <= allowed;
|
||||
if fits {
|
||||
self.fill_bytes_active
|
||||
.fetch_add(bytes as u64, Ordering::Relaxed);
|
||||
@@ -251,10 +237,6 @@ impl Cache {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Bound long-lived HOT RSS without flushing the working set. Only entries
|
||||
/// idle for the configured age are considered, and only while HOT usage is
|
||||
/// above the configured target waterline.
|
||||
fn trim_hot_idle(&self) {
|
||||
let settings = self
|
||||
.tier_settings
|
||||
@@ -285,17 +267,31 @@ impl Cache {
|
||||
.get(&key)
|
||||
.is_some_and(|entry| entry.last_access.elapsed() >= idle_cutoff);
|
||||
if !idle {
|
||||
// LRU order is also last-access order, so newer entries cannot qualify.
|
||||
break;
|
||||
}
|
||||
let Some(entry) = store.remove(&key) else { continue; };
|
||||
let Some(entry) = store.remove(&key) else {
|
||||
continue;
|
||||
};
|
||||
removed += 1;
|
||||
let scope_generation = store.scope_generations.get(&entry.scope).copied().unwrap_or(0);
|
||||
let key_generation = store.key_generations.get(&entry.base_key).copied().unwrap_or(0);
|
||||
let scope_generation = store
|
||||
.scope_generations
|
||||
.get(&entry.scope)
|
||||
.copied()
|
||||
.unwrap_or(0);
|
||||
let key_generation = store
|
||||
.key_generations
|
||||
.get(&entry.base_key)
|
||||
.copied()
|
||||
.unwrap_or(0);
|
||||
if !(settings.cold_enabled
|
||||
&& settings.cold_on_lru
|
||||
&& self.enqueue_demotion(
|
||||
key, entry, revision, generation, scope_generation, key_generation,
|
||||
key,
|
||||
entry,
|
||||
revision,
|
||||
generation,
|
||||
scope_generation,
|
||||
key_generation,
|
||||
))
|
||||
{
|
||||
self.counters.evictions.fetch_add(1, Ordering::Relaxed);
|
||||
@@ -307,29 +303,28 @@ impl Cache {
|
||||
}
|
||||
}
|
||||
|
||||
/// Block requests bound to an old immutable routing snapshot from creating
|
||||
/// cache tickets during a concurrent configuration publication. This does
|
||||
/// not clear HOT or COLD and does not modify the representation revision.
|
||||
pub fn set_control_revision(&self, revision: u64) {
|
||||
self.store.lock().unwrap_or_else(|e| e.into_inner()).control_revision = revision;
|
||||
self.store
|
||||
.lock()
|
||||
.unwrap_or_else(|e| e.into_inner())
|
||||
.control_revision = revision;
|
||||
}
|
||||
|
||||
pub fn replace_scope_revisions(&self, scopes: HashMap<String, u64>) {
|
||||
*self.scope_revisions.lock().unwrap_or_else(|e| e.into_inner()) = scopes;
|
||||
*self
|
||||
.scope_revisions
|
||||
.lock()
|
||||
.unwrap_or_else(|e| e.into_inner()) = scopes;
|
||||
}
|
||||
|
||||
pub fn configure(&self, settings: Settings) {
|
||||
*self.tier_settings.lock().unwrap_or_else(|e| e.into_inner()) = settings.clone();
|
||||
// Hot-applied limit reductions take effect immediately for published HOT
|
||||
// objects. Demotion is best effort and remains bounded by transient/COLD
|
||||
// queue budgets; otherwise the LRU object is dropped.
|
||||
let mut store = self.store.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let revision = store.revision;
|
||||
let generation = store.generation;
|
||||
let mut released_hot = false;
|
||||
while store.entries.len() > settings.max_entries || store.bytes > settings.max_bytes {
|
||||
let Some((_, key)) = store.lru.first_key_value().map(|(seq, key)| (*seq, *key))
|
||||
else {
|
||||
let Some((_, key)) = store.lru.first_key_value().map(|(seq, key)| (*seq, *key)) else {
|
||||
break;
|
||||
};
|
||||
let Some(old) = store.remove(&key) else {
|
||||
|
||||
Reference in new issue
Block a user