I am using Spring web flux and guava cache. In some of the examples they are using CacheMono.lookup to retrieve the value from the cache. I tried on the same lines and have following code.
CacheMono.lookup(key -> Mono.justOrEmpty(guavaCache.get(id, PhoneNumber.class))
.map(Signal::next), id)
.onCacheMissResume(() -> {
LOGGER.info("fetch from db");
return phoneNumberRepository.findById(id);})
.andWriteWith((key, signal) -> Mono.fromRunnable(() ->
Optional.ofNullable(signal.get())
.ifPresent(value -> {
if(value == null){
LOGGER.info("value is null");
}
LOGGER.info("value is not null "+value);
guavaCache.put(key, value);}))))
For the initial flow when guava cache does not contain the value it is fetching from db and storing into the cache. But for the same key when I send the request again, the cache has the value for the key. But CacheMono.lookup is still executing the fetch from db ( I am seeing LOGGER.info("fetch from db");.
But at the same time I am not seeing the logs LOGGER.info("value is not null "+value);
I am confused with this behavior. Why onCacheMissResume is called 2nd time when the cache has the data already.
You see LOGGER.info("fetch from db")
because it is called every time CacheMono
creates Mono<PhoneNumber>
to fetching from db. But this Mono<PhoneNumber>
won't be subscribed if the value exists in your cache.
You could examine it with logging onSubscribe
event:
.onCacheMissResume(() -> {
LOGGER.info("fetch from db");
return phoneNumberRepository.findById(id)
.doOnSubscribe(ignored -> LOGGER.info("really fetching from db"));
})