假設我有一些服務S接收到來自客戶端C的請求。 由於計算量過大,S不能立即響應,C也不能等到永遠,並且有他自己的超時期限。Spring MVC中的延遲計算
我的想法是實現服務器端如下所述: REST and long running jobs, Farazdagi
在我ServerController我有延遲計算一個線程池,併發圖來存儲響應。
private final int NUMBER_OF_WORKERS = 10;
private Map<String, ResponseEntity<MathResponse>> responseMap = new ConcurrentHashMap<>();
private ExecutorService executorService = Executors.newFixedThreadPool(NUMBER_OF_WORKERS);
我/calculate
測繪作業提交到線程池,並返回202 (Accepted)
HTTP狀態,並把重定向鏈接Location
頭。
@RequestMapping(value = "/calculate", method = RequestMethod.POST)
public ResponseEntity<String> startWorkflow(@RequestBody MathRequest request, UriComponentsBuilder builder) {
UUID uuid = UUID.randomUUID();
executorService.submit(() -> {
// time-consuming calculations here
ResponseEntity<MathResponse>response = HardMath.execute(request)
responseMap.put(uuid.toString(), response);
});
HttpHeaders headers = new HttpHeaders();
UriComponents uriComponents = builder.path("/wf/queue/{id}").buildAndExpand(uuid.toString());
headers.setLocation(uriComponents.toUri());
return new ResponseEntity<>(headers, HttpStatus.ACCEPTED);
}
在/queue/id
映射我返回的結果,如果它在地圖:
@RequestMapping(value = "/queue/{id}", method = RequestMethod.GET)
public ResponseEntity<MathResponse> getQueueInfo(@PathVariable("id") String id) {
ResponseEntity<MathResponse> defaultQueueResponse = new ResponseEntity<>(new MathResponse(), HttpStatus.OK);
return responseMap.getOrDefault(id, defaultQueueResponse);
}
我認爲,採用這種低層次的東西一樣ConcurrentHashMap
是不是一個好主意。 Spring中有沒有我可以使用的選項,而不是重新發明輪子?
看起來你的地圖永遠不會被清除。可能是這裏的內存泄漏。實際上,您可以使用任何存儲 - 在內存DB或隊列中,結果也是帶有序列化響應的消息。 – StanislavL
是的,我知道這一點。我只是想解釋一下這個想法,並展示一些我不信任的時刻。 –
你認爲其他一切都適用嗎? –