Project Reactor async在发生错误时重试发送电子邮件

时间:2017-06-01 14:41:37

标签: java project-reactor

我需要在用户注册后发送一些数据。我想在主线程中首次尝试,但是如果有任何错误,我想以10分钟的间隔重试5次。

@Override
public void sendRegisterInfo(MailData data) {
    Mono.just(data)
        .doOnNext(this::send)
        .doOnError(ex -> logger.warn("Main queue {}", ex.getMessage()))
        .doOnSuccess(d -> logger.info("Send mail to {}", d.getRecipient()))
        .onErrorResume(ex -> retryQueue(data))
        .subscribe();
}

private Mono<MailData> retryQueue(MailData data) {
    return Mono.just(data)
               .delayElement(Duration.of(10, ChronoUnit.MINUTES))
               .doOnNext(this::send)
               .doOnError(ex -> logger.warn("Retry queue {}", ex.getMessage()))
               .doOnSuccess(d -> logger.info("Send mail to {}", d.getRecipient()))
               .retry(5)
               .subscribe();
}

有效。 但我有一些问题:

  1. 我是否更正在doOnNext功能中进行操作?
  2. 使用delayElement在执行之间延迟是否正确?
  3. 等待延迟时线程是否被阻止?
  4. 重复错误并在它之间造成延迟的最佳做法是什么?

1 个答案:

答案 0 :(得分:6)

  1. doOnXXX用于记录很好。但是对于实际的元素处理,您必须更喜欢使用flatMap而不是doOnNext(假设您的处理是异步的/可以转换为返回Flux / Mono)。< / p>

  2. 这是正确的。另一种方法是转换代码并从Flux.interval开始,但此处delayElement是更好的IMO。

  3. 延迟在单独的线程/调度程序上运行(默认情况下为Schedulers.parallel()),因此不会阻塞主线程。

  4. Retry插件中实际上有reactor-extra个专用于此类用例的构建器:https://github.com/reactor/reactor-addons/blob/master/reactor-extra/src/main/java/reactor/retry/Retry.java