我了解了异步服务的一些想法,但没有编写很多代码,因此尤其是 Java 中的机制对我来说是新的。基本上,我有一个长时间运行的服务,我想将它分叉到另一个线程,并能够使用不同的服务检查它的状态。现在,我可以开始工作了,我还没有办法检查它。但更糟糕的是:
在下面的 POST 服务asyncUploadSoftLayerFile
中:
@RestController
@RequestMapping("/")
public class MyController {
...
@ResponseStatus(HttpStatus.CREATED)
@PostMapping("/async-files")
public DeferredResult<ResponseEntity<JobExecutionResult>> asyncUploadSoftLayerFile(@RequestParam MultipartFile file) throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, IOException, JobExecutionAlreadyRunningException{
logger.info("Received async-CompleteableFuture request");
DeferredResult<ResponseEntity<JobExecutionResult>> output = new DeferredResult<ResponseEntity<JobExecutionResult>>();
ForkJoinPool.commonPool().submit(() -> {
logger.info("Processing in separate thread: Thread-ID="+Thread.currentThread().getId());
JobExecutionResult jobExecutionResult = null;
try {
myReallyLongRunningProcess();
} catch (JobParametersInvalidException | JobExecutionAlreadyRunningException | JobRestartException
| JobInstanceAlreadyCompleteException | IOException e) {
logger.error("Error processing /async-files upload in Thread-ID: "+Thread.currentThread().getId(),e);
throw new RuntimeException(e);
}
if (!"COMPLETED".equals(jobExecutionResult.getExitStatus())) {
throw new UploadFileException(file.getOriginalFilename() + " exit status: " + jobExecutionResult.getExitStatus());
}
ResponseEntity<JobExecutionResult> responseEntity = ResponseEntity.ok(jobExecutionResult);
output.setResult(responseEntity);
});
return output;
}
}
Spring 确实做了延迟的事情,我可以看到它把工作交给了另一个线程。但它没有返回给调用者。相反,我看到:
2021-07-27 05:20:00 DEBUG o.s.web.servlet.DispatcherServlet - Exiting but response remains open for further handling
所以它只是部分地给了我想要的东西。我怎样才能让 Spring 将工作派生到另一个线程(并且理想情况下能够通过另一个 Web 服务调用引用该进程),但立即向 Web 浏览器返回某种响应?
这是开始工作的一部分,但会随着工作的进行跟踪完成的百分比。