title: Deferred calculations in Spring MVC
body: <p>Suppose I have some service S that receives requests from client C. 
  S cannot response immediately due to heavy calculations, C also cannot wait until forever and has his own timeout period.</p>
  
  <p>My idea is to implement the server side as described here: 
  <a href="http://farazdagi.com/blog/2014/rest-long-running-jobs/" rel="nofollow noreferrer">REST and long running jobs, Farazdagi</a></p>
  
  <p>In my ServerController I have a thread pool for deferred calculations and a concurrent map to store responses.</p>
  
  <pre><code>private final int NUMBER_OF_WORKERS = 10;
  private Map&lt;String, ResponseEntity&lt;MathResponse&gt;&gt; responseMap = new ConcurrentHashMap&lt;&gt;();
  private ExecutorService executorService = Executors.newFixedThreadPool(NUMBER_OF_WORKERS);
  </code></pre>
  
  <p>My <code>/calculate</code> mapping submits jobs to the thread pool and returns with <code>202 (Accepted)</code> HTTP status and puts redirection link to <code>Location</code> header.</p>
  
  <pre><code>@RequestMapping(value = "/calculate", method = RequestMethod.POST)
  public ResponseEntity&lt;String&gt; startWorkflow(@RequestBody MathRequest request, UriComponentsBuilder builder) {
      UUID uuid = UUID.randomUUID();
      executorService.submit(() -&gt; {
          // time-consuming calculations here
          ResponseEntity&lt;MathResponse&gt;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&lt;&gt;(headers, HttpStatus.ACCEPTED);
  }
  </code></pre>
  
  <p>In <code>/queue/id</code> mapping I return result if it's in the map:</p>
  
  <pre><code>@RequestMapping(value = "/queue/{id}", method = RequestMethod.GET)
  public ResponseEntity&lt;MathResponse&gt; getQueueInfo(@PathVariable("id") String id) {
      ResponseEntity&lt;MathResponse&gt; defaultQueueResponse = new ResponseEntity&lt;&gt;(new MathResponse(), HttpStatus.OK);
      return responseMap.getOrDefault(id, defaultQueueResponse);
  }
  </code></pre>
  
  <p>I suppose that using such low-level things like <code>ConcurrentHashMap</code> is not a good idea. Are there any options in Spring that I could use instead of reinventing the wheel?</p>