如何解决如何为Webflux应用程序包装阻塞IO操作
我有一个Spring Boot / Webflux应用程序。我需要一个执行以下操作的异步REST端点:
- 生成随机作业ID。
- 通过HTTP调用一项服务。
- 通过HTTP调用其他服务。
- 合并来自服务的响应并将结果写入文件。
- 将工作ID返回给客户端。
端点应该是异步的。这就是为什么客户不应该等待步骤2、3、4的结果。客户应立即收到工作ID。
现在我有以下实现:
@Override
public Mono<String> saveData() {
String jobId = UUID.randomUUID().toString();
Mono<ResponseFromService1> response1 = service1.getData();
Mono<ResponseFromService2> response2 = service2.getData();
return fileService.saveData(response1,response2)
.map(filePath -> log.info("File has been stored at {}",filePath))
.map(jobId);
service1和service2通过使用反应式WebClient来实现。 fileService.saveData的实现如下:
public Mono<Path> saveDataInFile(Mono<ResponseFromService1> response1,Mono<ResponseFromService2> response2) {
return Mono.fromCallable(() ->
Mono.zip(response1,response2)
.map(tuple -> blockingIOsaveMethod(tuple.getT1(),tuple.getT2()))
).publishOn(Schedulers.elastic())
.flatMap(mono -> mono);
}
问题在于此端点不是异步的。保存包含数据的文件后,端点的客户端将获得作业ID。 我应该如何更新saveDataInFile和saveData以立即返回作业ID?
解决方法
客户应立即收到工作ID。
这似乎表明Mono<String>
不是saveData()
的正确返回类型,因为您不想等待任何异步操作明显完成:
@Override
public String saveData() {
String jobId = UUID.randomUUID().toString();
// ...
return jobId;
}
...
看起来像“发射后遗忘”操作,您可以手动订阅Mono
:
@Override
public String saveData() {
String jobId = UUID.randomUUID().toString();
fileService.saveData(...).subscribe(...); // look at the different overloads of #subscribe(...)
return jobId;
}
请确保所有内容均已正确记录,以免跟踪HTTP响应后发生的情况。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。