Spring WebFlux com cache de memória

Sep 09 2020

Estou usando o fluxo da web do Spring e o cache de goiaba. Em alguns dos exemplos, eles estão usando CacheMono.lookup para recuperar o valor do cache. Tentei nas mesmas linhas e tenho o seguinte 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 o fluxo inicial, quando o cache de goiaba não contém o valor que está buscando do banco de dados e armazenando no cache. Mas para a mesma chave, quando eu enviar a solicitação novamente, o cache terá o valor da chave. Mas CacheMono.lookup ainda está executando a busca do db. ( I am seeing LOGGER.info("fetch from db");.Mas, ao mesmo tempo, não estou vendo os logs LOGGER.info("value is not null "+value);, estou confuso com esse comportamento. Por que onCacheMissResume é chamado pela segunda vez quando o cache já possui os dados.

Respostas

3 AlexanderPankin Sep 10 2020 at 07:32

Você vê LOGGER.info("fetch from db")porque ele é chamado toda vez que CacheMonocria Mono<PhoneNumber>para buscar do banco de dados. Mas isso Mono<PhoneNumber>não será registrado se o valor existir em seu cache.

Você pode examiná-lo com o registro de onSubscribeeventos:

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