0

I am using Express.js to initiate a computationally expensive task. I want to immediately respond to the request with an acknowledgement so the client knows the server has started working. Once the expensive task has finished, I want the server to tell the client the result of the process.

The only solution I've thought of is the client's request could include a URL for me to POST the answer. Upon POST'ing, the client could pick up the answer and use it appropriately; however, I am skeptical that this is the best approach. Is there a common idiom for handling cases like this?

Consider the following snippet. How would I send an answer to the client?

app.get("/getMeaningOfLife/", function(req, rsp) {
    rsp.send("Working on it now!");

    // This is expected to take a long time, but eventually returns "42"
    var meaningOfLife = computeMeaningOfLife();

    // send answer to client here    
    // HOW DO I DO THIS?
});
chessofnerd
  • 1,219
  • 1
  • 20
  • 40
  • 2
    The client may not even *have* a URL to post to. Instead, return Accepted with a Location header to poll for status/eventual success redirect: https://farazdagi.com/2014/rest-and-long-running-jobs/. – jonrsharpe Jul 02 '19 at 20:56
  • You will block your server if you do that. You won't be able to accept any other request while the task is being executed synchronously. If you could make your task asynchronous somehow, you could achieve what you want using streams – lleon Jul 02 '19 at 21:01
  • Take a look at the following question it may help you. But again, you should try to make that task asynchronous. https://stackoverflow.com/questions/6258210/how-can-i-output-data-before-i-end-the-response – lleon Jul 02 '19 at 21:04
  • @lleon, say the request is asynchonous; how would that solve the problem? I'd still need to send an acknowledgment and then send an answer. Am I missing something? (almost certainly yes!) – chessofnerd Jul 02 '19 at 21:07
  • Instead of `rsp.send()` use [`rsp.writeContinue()`](https://nodejs.org/api/http.html#http_response_writecontinue) Then at the end you can call `rsp.send()`. This is the standard way with HTTP to tell the client the request has been received and is processing. However, as has been pointed out, you should run the expensive computation in a separate process so you're not blocking the event loop. – Patrick Roberts Jul 02 '19 at 21:21
  • @jonrsharpe, I am successfully following the pattern in your link. If you would like to write up as an answer including the link, I would gladly accept it! – chessofnerd Jul 02 '19 at 22:19
  • As an alternative to polling, you might want to use a websocket or send an Event Stream response. – Bergi Jul 03 '19 at 06:11

0 Answers0