es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Spring Cache ejecutar acción después de que expire

Estoy utilizando Caffeine como gestor de caché integrado con Spring Cache para evitar descargas de archivos innecesarias. Una vez que descargo el archivo, tengo su ruta, que es devuelta por el método de descarga.

Me gustaría eliminar el archivo una vez que la caché expire. Intenté con removalListener pero parece que solo se activa cuando la caché se borra manualmente.

Esta es mi configuración de caché:

@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
}

¿Hay algo mal con este código? ¿Hay alguna forma de activar automáticamente el listener cuando la caché expire?</any,>

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El código parece correcto, pero el removalListener no se activa automáticamente cuando la caché expira. Esto se debe a que Caffeine solo activa el listener para eliminaciones explícitas o cuando la caché se está limpiando debido a su tamaño máximo u otras razones especificadas en su configuración.

    Para activar automáticamente el listener cuando la caché expira, puedes usar un hilo en segundo plano para limpiar periódicamente las entradas caducadas y activar el listener para cada una de ellas.

    Una forma de hacer esto es configurando una tarea programada que se ejecute a una tasa fija y elimine las entradas caducadas de la caché utilizando el método Cache#cleanUp(), que activa el removalListener para cada una de ellas.

    Aquí tienes un ejemplo de cómo configurar la tarea programada:

    @EnableScheduling
    @Configuration
    class CacheConfig {
    
        @Autowired
        lateinit var cacheManager: CacheManager
    
        @Scheduled(fixedRate = 5000) // se ejecuta cada 5 segundos
        fun cleanUpExpiredEntries() {
            val cache = cacheManager.getCache("myStoredData") // obtén la caché por nombre
            (cache.nativeCache as com.github.benmanes.caffeine.cache.Cache<*, *>).cleanUp() // elimina las entradas caducadas
        }
    }
    

    Esto llamará periódicamente a cleanUpExpiredEntries() cada 5 segundos y activará el removalListener para cada entrada caducada.

    Ten en cuenta que este enfoque puede afectar al rendimiento si el tamaño de la caché es grande, ya que implica iterar sobre todas las entradas de la caché para encontrar y eliminar las caducadas. Si el rendimiento es una preocupación, puedes considerar el uso de una implementación de caché diferente o ajustar la configuración de la caché para reducir su tamaño y tiempo de expiración.

Comments are closed.