WebFlux 在后台执行请求?

ika*_*ide 3 java spring spring-webflux

我的方法应该在执行confirm方法后返回结果或错误消息,然后执行一些后台作业。我写了与上面类似的内容,但我不确定then. 我错了吗?如果是,我如何使用 webflux 在后台运行方法?

    public Mono<Void> someMethod(...){
      return someReactiveApiClient.confirm().onErrorMap(...).then(doSomeBackgroundJob);
    }

Run Code Online (Sandbox Code Playgroud)

Abh*_*rty 6

正如 @zlaval 提到的,publishOn()可用于切换执行上下文。该publishOn运算符会影响线程上下文,在该线程上下文中,其下面的链中的其余运算符将在该上下文中运行,直到出现新的publishOn。所以放置的位置publishOn就很重要了。

您可以编写自己的调度程序或使用此类中现有的调度程序之一。你可以在这里读更多关于它的内容。

因此,如果您有这样的代码(我正在使用弹性调度程序):

    Mono.just("Hello").log()
        .onErrorMap(err -> new RuntimeException("my exception"))
        .publishOn(Schedulers.elastic())
        .then(Mono.just("World").log())
        .subscribe();
Run Code Online (Sandbox Code Playgroud)

您只会在控制台中看到打印的内容:

18:30:11.337 [main] INFO reactor.Mono.Just.1 - | onSubscribe([Synchronous Fuseable] Operators.ScalarSubscription)
18:30:11.340 [main] INFO reactor.Mono.Just.1 - | request(unbounded)
18:30:11.340 [main] INFO reactor.Mono.Just.1 - | onNext(Hello)
18:30:11.344 [main] INFO reactor.Mono.Just.1 - | onComplete()
18:30:11.344 [elastic-2] INFO reactor.Mono.Just.2 - | onSubscribe([Synchronous Fuseable] Operators.ScalarSubscription)
18:30:11.344 [elastic-2] INFO reactor.Mono.Just.2 - | request(unbounded)
18:30:11.344 [elastic-2] INFO reactor.Mono.Just.2 - | onNext(World)
18:30:11.344 [elastic-2] INFO reactor.Mono.Just.2 - | onComplete()

Process finished with exit code 0

Run Code Online (Sandbox Code Playgroud)

因此,第二个单声道正在World另一个调用的线程中执行elastic-2,而不是在main线程中执行。

请注意,如果您的confirm方法抛出错误,则后台任务将不会发生。执行将在那里停止。

例如。如果你有这样的事情:

    Mono.error(new ArithmeticException()).log()
        .onErrorMap(err -> new RuntimeException("my exception"))
        .publishOn(Schedulers.elastic())
        .then(Mono.just("World").log())
        .subscribe();
Run Code Online (Sandbox Code Playgroud)

然后运行它,将给出输出,

18:33:50.544 [main] INFO reactor.Mono.Error.1 - onSubscribe([Fuseable] Operators.EmptySubscription)
18:33:50.546 [main] INFO reactor.Mono.Error.1 - request(unbounded)
18:33:50.547 [main] ERROR reactor.Mono.Error.1 - onError(java.lang.ArithmeticException)
18:33:50.549 [main] ERROR reactor.Mono.Error.1 - 
java.lang.ArithmeticException: null
    at com.example.schooltimetable.Application.main(Application.java:29)

Process finished with exit code 0
Run Code Online (Sandbox Code Playgroud)

如果您的后台工作涉及一些 I/O 或网络调用,您也需要类似的操作。

    public Mono<Void> someMethod(...){
      return someReactiveApiClient.confirm()
               .onErrorMap(err -> {
                   //Your error handling logic. Remember to return an error
                   })
               .publishOn(Schedulers.elastic())
               .then(doSomeBackgroundJob);
    }
Run Code Online (Sandbox Code Playgroud)