Я работаю над мастерской проектного реактора и застрял со следующей задачей:
/**
* 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");
}
Может кто-нибудь выяснить, почему не происходит тайм-аут ? Я подозреваю, что механизм как-то не «привязан» к методу, вызываемому 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();
}