我是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

编辑

根据Michael Berry的回答,我将代码重构如下:

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包含该密钥的数据

最佳答案

这行:

.map(f -> this.logCache(k, f))


...很奇怪,因为您没有将任何内容映射到任何内容,而是在执行副作用(记录值)。在这里,doOnNext()(而不是map())将是一个更明智的选择。

但是,我离题了,这不是这里的主要问题。


  如何确保仅当不存在缓存的数据时才调用switchIfEmpty


就是这样,但是您的日志记录并未按照您的想法进行。这里可能引起您问题的关键概念是,null永远不会通过响应流传播。如果像在本示例中那样流为空,则什么都不会传播。

因此,在您的代码中,不会调用map()(也不会使用doOnNext()),因此您的“存在于缓存中”行将不会写入日志(因为没有要映射的值,也没有因此,在logCache()中检查该值是否为空是没有意义的-它永远不会为空。

据我所知,因此,此处的日志输出必须是两次getFoo()调用的结果:


第一个不在高速缓存中,因此未调用map(),未切换switchIfEmpty(),并打印了“查询远程服务”。
第二个存在于缓存中,因此打印了“存在于缓存中”行,未调用switchIfEmpty(),因此未显示“查询远程服务”。


为了使您的日志记录有意义,您应该从logCache()中删除​​条件逻辑,并在queryRemoteService()方法中添加“在缓存中不存在”行。

关于java - 如何开启单声道,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58974349/

10-09 01:04