Crystark
Crystark

Reputation: 4246

How can I have Reactor's Context work with Spring's cache?

So I have this particular use case where I'm combining the @Cacheable annotation with reactor and I want to access a value stored in the reactive context. Here is some sample code to reproduce the issue:

import com.github.benmanes.caffeine.cache.Caffeine
import org.springframework.cache.annotation.Cacheable
import org.springframework.cache.caffeine.CaffeineCache
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.scheduling.annotation.EnableScheduling
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Component
import org.springframework.stereotype.Service
import reactor.core.publisher.Mono
import reactor.util.context.Context
import java.util.concurrent.TimeUnit
import kotlin.random.Random

@EnableScheduling
@Configuration
class ZeConfig {
    @Bean
    fun myCache() = createCache("MyCacheName")

    private fun createCache(name: String) = CaffeineCache(
        name,
        Caffeine.newBuilder()
            .maximumSize(100)
            .removalListener<Any, Any> { key, _, cause ->
                println("Removal of $key: $cause")
            }
            .buildAsync(),
        false
    )
}

@Service
class ServiceWithCache {
    @Cacheable("MyCacheName", sync = true)
    fun get() = Mono.deferContextual { context ->
        println(context)
        // ... do something
        Mono.just(Random.nextInt(1000))
    }
}

@Component
class Example(private val serviceWithCache: ServiceWithCache) {
    @Scheduled(fixedRate = 5, timeUnit = TimeUnit.SECONDS)
    fun process() {
        val it = serviceWithCache
            .get()
            .contextWrite(Context.of("some-thing1", "lala1"))
            .block()
        println("Result: $it")
    }
}

This code output the following on the last run I did:

Context0{}
Result: 242
Result: 242
Result: 242
Result: 242
Result: 242

If I remove @Cacheable I get this:

Context1{some-thing1=lala1}
Result: 545
Context1{some-thing1=lala1}
Result: 216
Context1{some-thing1=lala1}
Result: 73

What I would like is this:

Context1{some-thing1=lala1}
Result: 242
Result: 242
Result: 242
Result: 242
Result: 242

I'm not sure I understand why I loose the context as soon as cache is set up.

How can I have Reactor's Context work with Spring's cache ?

EDIT: It seems that if I remove sync=true then I get what I expect. I may be wrong but this looks like a bug so I opened an issue sync=true on @Cacheable looses reactor's Context #33079

Upvotes: 0

Views: 111

Answers (0)

Related Questions