Symptom
LazyValueCacheTest.weightBoundedEviction fails intermittently in CI with:
LazyValueCacheTest.weightBoundedEviction:129 expected:<16> but was:<18>
First observed in the Remote File Service tests job for PR #603 (run https://github.com/eolivelli/herddb/actions/runs/26114979899).
Root cause
The test inserts 16 unique 64-byte entries into a 256-byte LazyValueCache and
asserts loaderCalls.get() == 16. Caffeine's weight-based eviction uses an async
write buffer; under CI resource pressure the maintenance thread can evict an entry
while the insertion loop is still running, causing getOrFetch to re-invoke the
loader for a key that was already loaded. The result is loaderCalls > 16 even
though exactly 16 distinct keys were inserted.
The cache.cleanUp() call at line 133 drains the buffer after the initial loop,
but eviction can begin (and trigger a reload on the next getOrFetch call in the
same loop) before the drain.
Fix ideas
- Assert
loaderCalls.get() >= 16 instead of == 16 (the test only needs to know
that every key was loaded at least once during the initial fill pass).
- Or: drain the cache before each iteration inside the fill loop so eviction never
races a subsequent call.
- Or: use a budget large enough to hold all 16 entries (16 × 64 = 1024 bytes) for
the initial fill assertion, then shrink the cache afterwards to test eviction.
Symptom
LazyValueCacheTest.weightBoundedEvictionfails intermittently in CI with:First observed in the Remote File Service tests job for PR #603 (run https://github.com/eolivelli/herddb/actions/runs/26114979899).
Root cause
The test inserts 16 unique 64-byte entries into a 256-byte
LazyValueCacheandasserts
loaderCalls.get() == 16. Caffeine's weight-based eviction uses an asyncwrite buffer; under CI resource pressure the maintenance thread can evict an entry
while the insertion loop is still running, causing
getOrFetchto re-invoke theloader for a key that was already loaded. The result is
loaderCalls > 16eventhough exactly 16 distinct keys were inserted.
The
cache.cleanUp()call at line 133 drains the buffer after the initial loop,but eviction can begin (and trigger a reload on the next
getOrFetchcall in thesame loop) before the drain.
Fix ideas
loaderCalls.get() >= 16instead of== 16(the test only needs to knowthat every key was loaded at least once during the initial fill pass).
races a subsequent call.
the initial fill assertion, then shrink the cache afterwards to test eviction.