java - 项目 react 器超时

标签 java project-reactor

我正在一个项目 react 堆研讨会上工作,并被困于以下任务:

/**
     * TODO 5
     * <p>
     * For each item call received in colors flux call the {@link #simulateRemoteCall} operation.
     * Timeout in case the {@link #simulateRemoteCall} does not return within 400 ms, but retry twice
     * If still no response then provide "default" as a return value
     */

我无法理解的问题是 Flux 实际上从未抛出 TimeOutException!我可以在控制台日志中观察到这一点:

16:05:09.759 [main] INFO Part04HandlingErrors - Received red delaying for 300 
16:05:09.781 [main] INFO Part04HandlingErrors - Received black delaying for 500 
16:05:09.782 [main] INFO Part04HandlingErrors - Received tan delaying for 300 

我尝试调整语句的顺序,尽管它似乎没有改变行为。注意:此外,我尝试了 timeout() 的重载变体,它接受默认值,如果没有发出任何元素,则应返回该默认值。

public Flux<String> timeOutWithRetry(Flux<String> colors) {

        return colors
                .timeout(Duration.ofMillis(400))
                //.timeout(Duration.ofMillis(400), Mono.just("default"))
                .retry(2)
                .flatMap(this::simulateRemoteCall)
                .onErrorReturn(TimeoutException.class, "default");

    }

有人可以解释一下为什么没有发生超时吗?我怀疑该机制在某种程度上没有“绑定(bind)”到 flatMap 调用的方法。

为了完整性:辅助方法:

public Mono<String> simulateRemoteCall(String input) {
        int delay = input.length() * 100;
        return Mono.just(input)
                .doOnNext(s -> log.info("Received {} delaying for {} ", s, delay))
                .map(i -> "processed " + i)
                .delayElement(Duration.of(delay, ChronoUnit.MILLIS));
    }

更完整,这是我用来验证功能的测试:

@Test
    public void timeOutWithRetry() {
        Flux<String> colors = Flux.just("red", "black", "tan");

        Flux<String> results = workshop.timeOutWithRetry(colors);

        StepVerifier.create(results).expectNext("processed red", "default", "processed tan").verifyComplete();
    }

最佳答案

Martin Tarjányi 的答案是正确的,但您还在代码中问了为什么

    return colors
            .timeout(Duration.ofMillis(400))
            //.timeout(Duration.ofMillis(400), Mono.just("default"))
            .retry(2)
            .flatMap(this::simulateRemoteCall)
            .onErrorReturn(TimeoutException.class, "default");

没有发生超时。

原因是,如果 colors 通量的元素可用,则调用 .timeout(Duration.ofMillis(400)) 没有效果,因为 如果在给定的 400 毫秒持续时间内没有发出任何项,则 timeout 仅传播 TimeoutException,但本例中并非如此。

因此,该元素被发出,并且 retry(2) 也没有效果。接下来,您对发出的元素调用 simulateRemoteCall,这需要一些时间,但不会返回错误。您的代码的结果(除了时间差异)与您简单地在给定通量上应用 map 相同:

public Flux<String> timeOutWithRetry(Flux<String> colors) {
    return colors.map(s -> "processed " + s);
}

如果您希望在调用 simulateRemoteCall 时看到超时,则必须在此调用后添加 timeout 方法。

您还可以使用 concatMap,而不是使用 flatMap。区别在于是否应保留顺序,即默认值是否可能无序出现。

使用concatMap,答案如下所示:

public Flux<String> timeOutWithRetry(Flux<String> colors) {
    return colors.concatMap(
            color -> simulateRemoteCall(color)
                        .timeout(Duration.ofMillis(400))
                        .retry(2)
                        .onErrorReturn("default"));
}

关于java - 项目 react 器超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59910548/

相关文章:

java - 在应用程序服务器中调用远程 Bean 与本地 Bean

java - 什么是原始类型,为什么我们不应该使用它呢?

java - 异步Java : How to organize nested subscribes that must be done sequentially?

java - 如何正确使用 Reactor Publisher

spring - 在通量上同时使用 publishOn 和 subscribeOn 不会导致任何事情发生

java - Tapestry +JDO+GAE

java - 通过电话线传输字符串数组

java - 将 Scala Future 转换为 Reactor Flux

java - 项目 Reactor 中的 Parallel Flux 与 Flux

java - WebView 无法从 wordpress 网站下载媒体(POST)