-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
I have an 'expire after access' cache (Caffeine version: 2.8.8) with values that I need to close (grpc managed channels). I have two close points:
- in removal listener - when value is not used for some time
- when my service is stopping - iterating cache.asMap().values() in order to close all that left
however, asMap iteration doesn't return expired values (which, seeing some posted issues, seems expected) , but the problem is that RemovalListener doesn't get notifications for expired entries.
There is a simple code that demonstrates this:
final LoadingCache<String, String> cache = Caffeine.newBuilder().weakKeys().removalListener((key, value, reason) -> {
System.out.println("[" + value + "] remove -(" + reason + ")");
}).expireAfterAccess(1, TimeUnit.SECONDS).build(key -> {
System.out.println("[" + key + "] create");
return key;
});
for (int i = 0; i < 10; i++) {
cache.get(String.valueOf(i));
}
Thread.sleep(2_000);
final Collection<String> values = cache.asMap().values();
System.out.println("cache.asMap() size: " + values.size());
for (final String value : values) {
System.out.println("->cache.asMap() value: " + value);
}
I found out that cache.cleanUp() just before cache asMap() will trigger expiration that notifies RemovalListener, but this just could mitigate the issue (will notify for some expirations). However, if an entry expire between cleanUp and asMap - this entry will still be lost.
I believe that triggered by cache.asMap iteration expirations shall notify RemovalListener.
Is there a way to implement that value cleanup correctly with current Caffeine release?