Spring WebFlux con cache in memoria

Sep 09 2020

Sto usando Spring web flux e guava cache. In alcuni degli esempi stanno usando CacheMono.lookup per recuperare il valore dalla cache. Ho provato sulle stesse linee e ho seguito il codice.

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

Per il flusso iniziale quando guava cache non contiene il valore che sta recuperando da db e memorizzato nella cache. Ma per la stessa chiave quando invio di nuovo la richiesta, la cache ha il valore per la chiave. Ma CacheMono.lookup sta ancora eseguendo il recupero da db ( I am seeing LOGGER.info("fetch from db");.Ma allo stesso tempo non vedo i log LOGGER.info("value is not null "+value);sono confuso con questo comportamento. Perché onCacheMissResume viene chiamato la seconda volta quando la cache ha già i dati.

Risposte

3 AlexanderPankin Sep 10 2020 at 07:32

Vedi LOGGER.info("fetch from db")perché viene chiamato ogni volta che CacheMonocrea Mono<PhoneNumber>per recuperare da db. Ma questo Mono<PhoneNumber>non verrà sottoscritto se il valore esiste nella cache.

Puoi esaminarlo con l' onSubscribeevento di registrazione :

.onCacheMissResume(() -> {
    LOGGER.info("fetch from db");
    return phoneNumberRepository.findById(id)
        .doOnSubscribe(ignored -> LOGGER.info("really fetching from db"));
})