Boot Pros,
我最近开始在春季开机时编程,我偶然发现了一个问题,我希望得到你的意见。
我尝试实现的目标:
GET
的{{1}}端点。这个nonBlockingEndpoint
执行一个非常长的操作,资源很重,可以运行20到40秒。(在附加的代码中,它被nonBlockingEndpoint
模仿)Thread.sleep()
时,spring应用程序应该注册该调用并立即将操作ID返回给调用者。nonBlockingEndpoint
上查询此操作的状态。在开始时它将被启动,并且一旦控制器完成服务reuqest,它将是诸如queryOpStatus
的代码。然后,调用者知道他的请求已在服务器上成功完成。我找到的解决方案:
SERVICE_OK
注册新操作已启动APIOperationsManager
java构造使用CompletableFuture
CompletableFuture.supplyAsync(() -> {}
通过API Operations Manager更新操作状态以下是代码:
cf.thenRun()
这里也是用于completness的APIOperationsManager.java:
@GetMapping(path="/nonBlockingEndpoint")
public @ResponseBody ResponseOperation nonBlocking() {
// Register a new operation
APIOperationsManager apiOpsManager = APIOperationsManager.getInstance();
final int operationID = apiOpsManager.registerNewOperation(Constants.OpStatus.PROCESSING);
ResponseOperation response = new ResponseOperation();
response.setMessage("Triggered non-blocking call, use the operation id to check status");
response.setOperationID(operationID);
response.setOpRes(Constants.OpStatus.PROCESSING);
CompletableFuture<Boolean> cf = CompletableFuture.supplyAsync(() -> {
try {
// Here we will
Thread.sleep(10000L);
} catch (InterruptedException e) {}
// whatever the return value was
return true;
});
cf.thenRun(() ->{
// We are done with the super long process, so update our Operations Manager
APIOperationsManager a = APIOperationsManager.getInstance();
boolean asyncSuccess = false;
try {asyncSuccess = cf.get();}
catch (Exception e) {}
if(true == asyncSuccess) {
a.updateOperationStatus(operationID, Constants.OpStatus.OK);
a.updateOperationMessage(operationID, "success: The long running process has finished and this is your result: SOME RESULT" );
}
else {
a.updateOperationStatus(operationID, Constants.OpStatus.INTERNAL_ERROR);
a.updateOperationMessage(operationID, "error: The long running process has failed.");
}
});
return response;
}
我提出的问题
我很乐意收到您的反馈。
非常感谢, 彼得P
答案 0 :(得分:1)
使用一个请求提交长时间运行的任务是一种有效的模式,返回一个允许客户端稍后询问结果的ID。
但我建议重新考虑一些事情:
此外,还有一些您可能还想更改的低级别实施问题:
希望这有帮助。
我是否需要对数据库进行事务处理?
只要您只编写/更新一行,就不需要进行此事务处理,因为这确实是&#39; atomic&#39;。
如果您一次编写/更新多行,您应该使其成为事务性保证,所有行都被更新或者没有。
但是,如果两个操作(可能来自两个客户端)更新同一行,则最后一个操作将获胜。