Issue Description
Cache.messages defaults to 50 MiB, but Cache::new() constructs quick_cache::sync::Cache without specifying a shard count. quick-cache therefore defaults to four shards per detected CPU, with independent capacity per shard.
A MessageStoreCache larger than one shard’s hot allocation is evicted during PlaceholderGuard::insert(). quick-cache returns Ok(()) for this case, so Stalwart treats the insertion as successful. The next access misses and runs another full_cache_build().
MessageStoreCache constructions
Expected Behavior
A MessageStoreCache smaller than the configured total Cache.messages size should remain cacheable, or Stalwart should detect and report failed admission.
Actual Behavior
Entries too large for the cache are silently discarded and then constantly re-inserted causing extremely high database load
Reproduction Steps
Here’s a test:
#[cfg(test)]
mod tests {
use super::*;
#[derive(Clone, Debug)]
struct WeightedValue(u64);
impl CacheItemWeight for WeightedValue {
fn weight(&self) -> u64 {
self.0
}
}
#[tokio::test]
async fn placeholder_insert_retains_value_smaller_than_total_capacity() {
let cache =
Cache::<u32, WeightedValue>::new_estimated(1024, 50 * 1024 * 1024);
assert!(cache.inner().num_shards() > 1);
let value = WeightedValue(cache.inner().shard_capacity());
assert!(value.weight() < cache.inner().capacity());
let guard = cache
.get_value_or_guard_async(&1)
.await
.expect_err("cache should initially miss");
assert!(guard.insert(value).is_ok());
assert!(
cache.get(&1).is_some(),
"insert returned Ok but the value was not retained"
);
}
}
Stalwart Version
v0.16.x
Installation Method
Docker
Database Backend
PostgreSQL
Blob Storage
S3-compatible
Search Engine
PostgreSQL
Directory Backend
OIDC
I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.
on
I have searched this support forum (open and closed topics) and confirm this is not a duplicate.
on
I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.
on