Spring WebFlux con memoria caché

Sep 09 2020

Estoy usando Spring web flux y guava cache. En algunos de los ejemplos, están usando CacheMono.lookup para recuperar el valor de la caché. Intenté en las mismas líneas y tengo el siguiente código.

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

Para el flujo inicial cuando guava cache no contiene el valor que está obteniendo de db y almacenando en el cache. Pero para la misma clave cuando vuelvo a enviar la solicitud, el caché tiene el valor de la clave. Pero CacheMono.lookup todavía está ejecutando la recuperación de db. ( I am seeing LOGGER.info("fetch from db");.Pero al mismo tiempo no veo los registros LOGGER.info("value is not null "+value);, estoy confundido con este comportamiento. Por qué onCacheMissResume se llama por segunda vez cuando el caché ya tiene los datos.

Respuestas

3 AlexanderPankin Sep 10 2020 at 07:32

Verá LOGGER.info("fetch from db")porque se llama cada vez que CacheMonocrea Mono<PhoneNumber>para recuperar de db. Pero esto Mono<PhoneNumber>no se suscribirá si el valor existe en su caché.

Puede examinarlo con el onSubscribeevento de registro :

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