【问题标题】:Spring webflux how to return 200 response to client before processing large fileSpring webflux如何在处理大文件之前向客户端返回200响应
【发布时间】:2020-05-11 01:46:13
【问题描述】:

我正在开发一个 Spring webflux 项目,

我想做一些事情,当客户端调用 API 时,我想向客户端发送成功消息并在后台执行大文件操作。

所以客户不必等到我的整个文件处理完毕。

为了试用,我制作了如下示例代码

REST 控制器

@GetMapping(value = "/{jobId}/process")
  @ApiOperation("Start import job")
  public Mono<Integer> process(@PathVariable("jobId") long jobId) {
    return service.process(jobId);
  }

文件处理服务

public Mono<Integer> process(Integer jobId) {
    return repository
        .findById(jobId)
        .map(
            job -> {
              File file = new File("read.csv");
              return processFile(file);
            });
  }

下面是我的堆栈

Spring Webflux 2.2.2.RELEASE

我尝试使用 WebClient 进行此调用,但在未处理整个文件之前我没有收到响应。

谁能帮帮我。

谢谢

阿尔佩什

【问题讨论】:

    标签: spring rx-java reactive-programming spring-webflux java-9


    【解决方案1】:

    您可以使用subscribe 方法并在后台启动具有自己作用域的作业。

    Mono.delay(Duration.ofSeconds(10)).subscribeOn(Schedulers.newElastic("myBackgroundTask")).subscribe(System.out::println);
    

    只要您不使用 zip/merge 或类似运算符之一将其绑定到您的响应发布者,您的作业将在其自己的调度程序池的后台运行。

    subscribe() 方法返回一个Disposable 实例,以后可以通过调用dispose() 方法来取消后台作业。

    【讨论】:

    • 但是这是如何执行的呢?由于订阅方法返回 Disposable,我想在后台运行它,谁来使用它?
    • 你可以把它放在你的job lambda 中。如果您出于某种原因需要取消此后台作业,您只需要Disposable。如果你没有这个要求,你可以忽略它。
    【解决方案2】:

    作为选项之一,您可以在不同的线程中运行处理。

    例如:

    1. 创建一个Event Listener Link

    2. 启用@Async@EnableAsyncLink

    或者使用Java并发包中Executors的不同类型

    或者手动运行线程

    对于 Kotlin,您也可以使用 Coroutines

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-02
      • 1970-01-01
      • 2012-08-14
      • 1970-01-01
      • 2019-11-14
      • 2020-11-26
      • 1970-01-01
      • 2017-12-21
      相关资源
      最近更新 更多