繁体   English   中英

是否可以在 Mono/Flux 中创建动态过滤器/谓词?

[英]Is it possible to create a dynamic filter/predicate in Mono/Flux?

该应用程序是一个简单的处理 - 读取数据,过滤它,处理和写入过滤后的数据。

这是一个运行没有任何问题的简单代码:

  void run() {
    Flux.interval(Duration.ofMillis(200))
        .filter(value -> getPredicate().test(value))
        .flatMap(this::writeData)
        .subscribe();
  }

  private Predicate<Long> getPredicate() {
    return value -> value % 2 == 0;
  }

是否可以通过定期请求从远程 web 服务中检索动态谓词? 如果可能 - 如何使用 Mono<Predicate> inside.filter() 并保持非阻塞

例如将 getPredicate() 替换为以下内容:

  private Mono<Predicate<Long>> getPredicateFromRemoteServer() {
    return webClient.get()
        .uri("/filters/1")
        .retrieve()
        .bodyToMono(Filter.class)
        .map(this::mapToPredicate)
        .cache(v -> Duration.ofMinutes(10), ex -> Duration.ZERO, () -> Duration.ZERO);
  }

  private Predicate<Long> mapToPredicate(Filter filter) {
    // here will be converting filter object into predicate
    return value -> value > 5;
  }

理想情况下,我想避免使用 cache(Duration.ofMinutes(10)) 因为过滤器可以每分钟或每天更新一次......一旦过滤器更新,我的服务就会收到通知,但我没有找到使缓存无效的方法在外部,这就是为什么 Duration.ofMinutes(10) 用于一些近似失效的原因。

好吧,也许您可以稍微不同地编写管道。 每次您通过调用getPredicateFromRemoteServer()处理 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ 中的项目时,您不必希望返回一个新的Predicate ,而是可以将 function 本身作为您的谓词。 从 stream 传递您正在处理的值,并使其返回带有答案的Mono<Boolean>并在过滤器中使用它,当filterWhen在您的管道中时。

例如,有点像这样:

private Mono<Boolean> isWithinThreshold(int value) {
    return webClient.get()
        .uri("/filters/1")
        .retrieve()
        .bodyToMono(Filter.class)
        .map(filter -> filter.threshold <= value)
        .cache(v -> Duration.ofMinutes(10), ex -> Duration.ZERO, () -> Duration.ZERO);
  }

然后在您的主管道中,您可以执行以下操作:

Flux.interval(Duration.ofMillis(200))
        .filterWhen(value -> isWithinThreshold(value))
        .flatMap(this::writeData)
        .subscribe();
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM