Shaunyl
Shaunyl

Reputation: 594

Caffeine with kotlin, spring boot and suspend functions

since I cannot use Caffeine and Spring Boot annotations (@Cacheable etc..) with Kotlin suspend functions, I am trying to implement it manually.

I have this method to retrieve a Shopping Cart from a cookie value:

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

I have added this to the application.yml file:

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

And this configuration:

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

Unfortunately I keep getting in the logs this message. Meaning that even if the key is exactly the same, it is duplicated in the cache:

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==

Why? And how to resolve? Thanks

EDIT:

Using Deferred it works:

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

Upvotes: 0

Views: 430

Answers (0)

Related Questions