本文介紹了如何包裝WebFlux應(yīng)用程序的阻塞IO操作的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!
問題描述
我有一個Spring Boot/Webflow應(yīng)用程序。我需要具有以下功能的異步REST終結(jié)點:
-
生成隨機(jī)作業(yè)ID。
通過HTTP調(diào)用一個服務(wù)。
通過HTTP調(diào)用其他服務(wù)。
組合來自服務(wù)的響應(yīng)并將結(jié)果寫入文件。
將作業(yè)ID返回給客戶端。
終結(jié)點應(yīng)為異步。這就是為什么客戶端不應(yīng)該等待步驟2、3、4的結(jié)果。客戶端應(yīng)該立即收到作業(yè)ID。
目前我有以下實現(xiàn):
@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實現(xiàn)的。
FileService.saveData的實現(xiàn)如下:
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);
}
問題是此終結(jié)點不是異步的。端點的客戶端在保存包含數(shù)據(jù)的文件后獲取作業(yè)ID。
我應(yīng)該如何更新saveDataInFile和saveData以立即返回作業(yè)ID?
推薦答案
客戶端應(yīng)立即收到作業(yè)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;
}
確保所有內(nèi)容都被記錄在案,這樣您就不會忘記返回HTTP響應(yīng)后發(fā)生的事情。
這篇關(guān)于如何包裝WebFlux應(yīng)用程序的阻塞IO操作的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,