I'm new to Webflux and I'm trying to implement this scenario:
- client ask for data
- if data is already present in redis cache => return cached data
- otherwise query remote service for data
I've written this code:
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
}
It prints:
"Querying remote service"
"Foo # test_key # present in cache"
How can I ensure that switchIfEmpty
is called only if cached data is not present?
Edit
Accordingly to Michael Berry's answer I refactored my code like follows:
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
}
Now my output is this:
Trying to get cached test_key data
PRESENT
Querying provider
So it seems that is executed only one time, but still can't avoid switchIfEmpty is executed. I'm sure that redis contains data for that key