咖啡因与kotlin,弹簧启动和暂停功能

Caffeine with kotlin, spring boot and suspend functions

提问人:Shaunyl 提问时间:10/22/2023 最后编辑:Shaunyl 更新时间:10/22/2023 访问量:56

问:

由于我无法将 Caffeine 和 Spring Boot 注释(@Cacheable等)与 Kotlin 挂起函数一起使用,因此我正在尝试手动实现它。

我有这个方法可以从cookie值中检索购物车:

@CacheConfig(cacheNames = ["shopping-cart"])
class ShoppingCartService {
suspend fun getShoppingCartWithItemsCount(cartCookieValue: String?): ShoppingCart {
    if (cartCookieValue == null) return ShoppingCart(-1)
    return cacheManager.getCache("shopping-cart")?.get<ShoppingCart>(cartCookieValue).also { shoppingCart ->
        if (shoppingCart == null) log.info("Shopping cart with id $cartCookieValue not found in cache")
        else log.info("Shopping with id $cartCookieValue found in cache")
    } ?: suspend {
        return getShoppingCart(cartCookieValue)
        }.also {
            log.info("Add to cache key $cartCookieValue")
            cacheManager.getCache("shopping-cart")?.put(cartCookieValue, it)
        }
            ?: run { throw RuntimeException("Invalid shopping cart") }
        shoppingCart
    }.invoke()
}
}

我已将其添加到文件中:application.yml

spring.cache:
    cache-names: shopping-cart
    caffeine.spec: maximumSize=500,expireAfterAccess=600s

而这个配置:

@EnableCaching
...

@Bean
fun cacheManager(): CacheManager {
    val cacheManager = CaffeineCacheManager()
    cacheManager.setCaffeine(caffeineCacheBuilder())
    return cacheManager
}

@Bean
fun caffeineCacheBuilder(): Caffeine<Any, Any> {
    return Caffeine.newBuilder()
        .maximumSize(500)
        .expireAfterWrite(10, TimeUnit.MINUTES)
        .weakKeys()
        .recordStats()
}

不幸的是,我一直在日志中收到此消息。这意味着即使密钥完全相同,它也会在缓存中复制:

2023-10-21T22:55:17.110+02:00  INFO 90127 --- [actor-tcp-nio-1] c.s.c.s.c.ShoppingCartService   : Add to cache key MTM3OjE2OTcyMjI0jEzMTI6OWVmNzlmYTc1YzY0ZGU0NTFiMDJhOTQ3NWE5NGQzYTkyZWVkMzlhZjZhNGMzZGMzZTI1Y0NmE3MGU4YzNiNQ==

为什么?以及如何解决? 谢谢

编辑:

使用 Deferred,它可以工作:

@Cacheable(sync = true, key = "#cartCookieValue")
fun getShoppingCartWithItemsCount(cartCookieValue: String?): Deferred<ShoppingCart> =
    CoroutineScope(Dispatchers.Default).async {
        delay(5000)
        cartCookieValue?.let { value ->
            return getShoppingCart(value)
        } ?: ShoppingCart(-1)
    }
Spring spring-boot kotlin 暂停咖啡 因缓存

评论


答: 暂无答案