Skip to content

Commit 79cc2b5

Browse files
committed
NoSQL: Update test for Caffeine 3.2.3
The read of `Eviction` properties is "just" a volatile read since Caffeine 3.2.3 and trigger cleanups asynchronously. Before 3.2.3, cleanups happened synchronously. This change breaks the initially present assertions of this test, but not the functionality of the production code. See ben-manes/caffeine#1897
1 parent 2daa2c8 commit 79cc2b5

File tree

2 files changed

+34
-10
lines changed

2 files changed

+34
-10
lines changed

persistence/nosql/persistence/impl/src/main/java/org/apache/polaris/persistence/nosql/impl/cache/CaffeineCacheBackend.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ class CaffeineCacheBackend implements CacheBackend {
123123
var cacheBuilder =
124124
Caffeine.newBuilder()
125125
.executor(executor)
126-
.scheduler(Scheduler.systemScheduler())
126+
.scheduler(Scheduler.disabledScheduler())
127127
.ticker(config.clockNanos()::getAsLong)
128128
.maximumWeight(capacityBytes)
129129
.weigher(this::weigher)
@@ -260,6 +260,7 @@ void cachePut(CacheKeyValue key, CacheKeyValue value) {
260260
} else {
261261
rejections.incrementAndGet();
262262
rejectionsWeight.accept(w);
263+
cache.cleanUp();
263264
}
264265
}
265266

persistence/nosql/persistence/impl/src/test/java/org/apache/polaris/persistence/nosql/impl/cache/TestCacheOvershoot.java

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,21 @@
5050
public class TestCacheOvershoot {
5151
@InjectSoftAssertions protected SoftAssertions soft;
5252

53+
/** This simulates the production setup. */
5354
@RepeatedTest(3) // consider the first repetition as a warmup (C1/C2)
5455
public void testCacheOvershootDirectEviction() throws Exception {
55-
testCacheOvershoot(Runnable::run);
56+
testCacheOvershoot(Runnable::run, true);
5657
}
5758

59+
/** This test <em>illustrates</em> delayed eviction, leading to more heap usage than admitted. */
5860
@RepeatedTest(3) // consider the first repetition as a warmup (C1/C2)
5961
public void testCacheOvershootDelayedEviction() throws Exception {
6062
// Production uses Runnable::run, but that lets this test sometimes run way too
6163
// long, so we introduce some delay to simulate the case that eviction cannot keep up.
62-
testCacheOvershoot(t -> delayedExecutor(2, TimeUnit.MILLISECONDS).execute(t));
64+
testCacheOvershoot(t -> delayedExecutor(2, TimeUnit.MILLISECONDS).execute(t), false);
6365
}
6466

65-
private void testCacheOvershoot(Executor evictionExecutor) throws Exception {
67+
private void testCacheOvershoot(Executor evictionExecutor, boolean direct) throws Exception {
6668
var meterRegistry = new SimpleMeterRegistry();
6769

6870
var config =
@@ -119,20 +121,41 @@ private void testCacheOvershoot(Executor evictionExecutor) throws Exception {
119121
});
120122
}
121123

122-
for (int i = 0; i < 50 && !seenOvershoot; i++) {
124+
for (int i = 0; i < 50; i++) {
123125
Thread.sleep(10);
124126
var w = cache.currentWeightReported();
125-
if (w > maxWeight) {
127+
if (w > admitWeight) {
126128
seenOvershoot = true;
127129
}
128130
}
129131

130132
stop.set(true);
131133
}
132134

133-
soft.assertThat(cache.currentWeightReported()).isLessThanOrEqualTo(admitWeight);
134-
soft.assertThat(cache.rejections()).isEqualTo(0L);
135-
soft.assertThat(meterRejectedWeight.totalAmount()).isEqualTo(0d);
136-
soft.assertThat(seenOvershoot).isFalse();
135+
// The read of `Eviction` properties is a plain volatile read since Caffeine version 3.2.3
136+
// and trigger cleanups asynchronously. Before 3.2.3, cleanups happened synchronously.
137+
// This change breaks the initially present assertions of this test, but not the
138+
// functionality of the production code.
139+
// See https://github.com/ben-manes/caffeine/issues/1897
140+
if (direct) {
141+
soft.assertThat(cache.currentWeightReported()).isLessThanOrEqualTo(admitWeight);
142+
143+
// We will (with a good probability) see no rejections with direct eviction. But it can still
144+
// happen,
145+
// so we cannot have the following two assertions. Rejections are expected.
146+
// soft.assertThat(cache.rejections()).isEqualTo(0L);
147+
// soft.assertThat(meterRejectedWeight.totalAmount()).isEqualTo(0d);
148+
soft.assertThat(seenOvershoot).isFalse();
149+
} else {
150+
// Note: we cannot ensure that the current weight is limited to the admitted weight with
151+
// asynchronous eviction.
152+
153+
// We will (with an extremely high probability) see the current weight exceed the admitted
154+
// weight with
155+
// delayed eviction.
156+
soft.assertThat(cache.rejections()).isGreaterThan(0L);
157+
soft.assertThat(meterRejectedWeight.totalAmount()).isGreaterThan(0d);
158+
soft.assertThat(seenOvershoot).isTrue();
159+
}
137160
}
138161
}

0 commit comments

Comments
 (0)