Reputation: 1363
I'm using Caffeine as Cache Manager integrated with Spring Cache to avoid multiple unnecesary file downloads. Once I download the file, I have its path, which is returned by the download method.
I would like to delete the file once the cache expires. I tried with removalListener
but it seems it is only triggered when cache is manually cleared.
This is my cache configuration:
@Bean
fun getCacheBuilder() = Caffeine.newBuilder()
.expireAfterWrite(3, TimeUnit.SECONDS)
.removalListener { _: Any?, filePath: Any?, _: RemovalCause ->
Files.delete(Paths.get(filePath.toString()))
}
@Bean
fun getCacheManager(caffeine: Caffeine<Any, Any>): CacheManager {
val caffeineCacheManager = CaffeineCacheManager("myStoredData")
caffeineCacheManager.setCaffeine(caffeine)
return caffeineCacheManager
}
Is there something wrong with this code? Is there any way to automatically trigger the listener when the cache expires?
Upvotes: 2
Views: 1974
Reputation: 1504
For those who come here with the same question, but regarding Redis:
I've done this in next way, using Spring's @EventListener
.
@Slf4j
@EnableRedisRepositories(enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP)
@Configuration
public class RedisListenerConfig {
@EventListener
public void handleRedisKeyExpiredEvent(RedisKeyExpiredEvent<String> event) {
String eventId = new String(event.getId());
log.info("Key {} has expired. Value {}", eventId, event.getValue());
}
}
The whole manual can be found here Baeldung.com
Working on Java 17 and Spring Boot 3.x.x as well as on Java 8 and Spring Boot 2.5.x
Upvotes: 0
Reputation: 9621
By default expiration is handled as a side-effect of other activity on the cache triggering a maintenance cycle. If the cache is idle then the notification will be delayed. To resolve this you will need a thread to schedule expiration events on, so that it can trigger a cache.cleanUp()
call. This can be done using Caffeine.scheduler(Scheduler) configuration. The systemScheduler
relies on a Java 9+ feature of a JVM-wide scheduler thread.
Caffeine.newBuilder()
.expireAfterWrite(3, TimeUnit.SECONDS)
.scheduler(Scheduler.systemScheduler())
.removalListener { _: Any?, filePath: Any?, _: RemovalCause ->
Files.delete(Paths.get(filePath.toString()))
}
Upvotes: 2