Spring WebFlux avec cache mémoire
J'utilise le flux Web Spring et le cache de goyave. Dans certains des exemples, ils utilisent CacheMono.lookup pour récupérer la valeur du cache. J'ai essayé sur les mêmes lignes et j'ai le code suivant.
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);}))))
Pour le flux initial lorsque le cache de goyave ne contient pas la valeur qu'il extrait de la base de données et le stocke dans le cache. Mais pour la même clé lorsque j'envoie à nouveau la demande, le cache a la valeur de la clé. Mais CacheMono.lookup exécute toujours la récupération à partir de la base de données ( I am seeing LOGGER.info("fetch from db");.Mais en même temps, je ne vois pas les journaux, LOGGER.info("value is not null "+value);je suis confus avec ce comportement. Pourquoi onCacheMissResume est appelé la deuxième fois alors que le cache contient déjà les données.
Réponses
Vous voyez LOGGER.info("fetch from db")parce qu'il est appelé à chaque fois qu'il CacheMonocrée Mono<PhoneNumber>pour récupérer à partir de la base de données. Mais cela Mono<PhoneNumber>ne sera pas abonné si la valeur existe dans votre cache.
Vous pouvez l'examiner avec l' onSubscribeévénement de journalisation :
.onCacheMissResume(() -> {
LOGGER.info("fetch from db");
return phoneNumberRepository.findById(id)
.doOnSubscribe(ignored -> LOGGER.info("really fetching from db"));
})