Я новичок в Webflux и пытаюсь реализовать этот сценарий:
- клиент запрашивает данные
- если данные уже присутствуют в кеше Redis => вернуть кешированные данные
- в противном случае запросить данные в удаленной службе
Я написал этот код:
ReactiveRedisOperations<String, Foo> redisOps;
private Mono<Foo> getFoo(String k) {
return this.redisOperations.opsForValue().get(k)
.map(f -> this.logCache(k, f))
.switchIfEmpty(this.queryRemoteService(k));
}
private void logCache(String k, Foo f) {
this.logger.info("Foo # {} # {} present in cache. {}",
k,
null != f ? "" : "NOT",
null != f ? "" : "Querying remote");
}
private Mono<Foo> queryRemoteService(String k) {
this.logger.info("Querying remote service");
// query code
}
Он печатает:
"Querying remote service"
"Foo # test_key # present in cache"
Как я могу гарантировать, что switchIfEmpty
вызывается только в том случае, если кэшированные данные отсутствуют?
Изменить
В соответствии с ответом Майкла Берри я реорганизовал свой код следующим образом:
private Mono<Foo> getFoo(String k) {
this.logger.info("Trying to get cached {} data", k);
this.logger.info(this.redisOps.hasKey(k).block() ? "PRESENT" : "NOT present");
return this.redisOperations.opsForValue().get(k)
.switchIfEmpty(this.queryRemoteService(k));
}
private Mono<Foo> queryRemoteService(String k) {
this.logger.info("Querying remote service");
// query code
}
Теперь мой вывод таков:
Trying to get cached test_key data
PRESENT
Querying provider
Таким образом, кажется, что выполняется только один раз, но все же не удается избежать выполнения switchIfEmpty. Я уверен, что redis содержит данные для этого ключа
switchIfEmpty()
, если возвращается значение. 21.11.2019.opsForValue().get(k)
и подтвердить, что он определенно возвращает значение? 21.11.2019