-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Closed
Description
The expireAfterWrite timestamp for an async load should be computed when the CompletableFuture is complete and not when it is put into the cache, right? It looks like there's an after-write maintenance task to make incomplete CompletableFutures unevictable after the CompletableFuture is first put into the cache, but if the CompletableFuture is completed before that maintenance task runs, then the write timestamp would be incorrect.
Here's a failing test case of the issue:
@Test
public void writeTimeRaceCondition() {
FakeTicker ticker = new FakeTicker();
CountDownLatch latch = new CountDownLatch(1);
AsyncCache<String, String> cache =
Caffeine.newBuilder()
.executor(
command ->
commonPool()
.execute(
() -> {
awaitUninterruptibly(latch);
command.run(); // afterWrite maintenance task
}))
.expireAfterWrite(Duration.ofMillis(5))
.ticker(ticker::read)
.buildAsync();
CompletableFuture<String> future = cache.get("key", (k, e) -> new CompletableFuture<>());
ticker.advance(Duration.ofMillis(10));
future.complete("value");
latch.countDown();
assertThat(cache.getIfPresent("key")).isNotNull();
ticker.advance(Duration.ofMillis(4));
assertThat(cache.getIfPresent("key")).isNotNull();
ticker.advance(Duration.ofMillis(1));
assertThat(cache.getIfPresent("key")).isNull();
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels