本文介紹了如何包裝WebFlux應用程序的阻塞IO操作的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我有一個Spring Boot/Webflow應用程序。我需要具有以下功能的異步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是使用Reactive 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;
}
...
看起來像是一個<2-2]操作,您或許可以手動訂閱Mono
:
@Override
public String saveData() {
String jobId = UUID.randomUUID().toString();
fileService.saveData(...).subscribe(...); // look at the different overloads of #subscribe(...)
return jobId;
}
確保所有內容都被記錄在案,這樣您就不會忘記返回HTTP響應后發生的事情。
這篇關于如何包裝WebFlux應用程序的阻塞IO操作的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,