Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the node.js patterns for returning response to client via worker process [closed]

If I have want to handle client requests using a web server, messaging queue and x N worker processes, what are the usual patterns?

What I can think of are:

  1. Worker take the job from queue, process it, save the result for client to poll. So there is no communication between the web server and worker

  2. Worker take the job from queue, process it, send it to a result queue, which will be consumed by the web server(how to do this with express?), then web server sends it back to client. Meanwhile client will be waiting (is this still called a long polling?)

  3. Web server return a response immediately, push the job to worker queue. Worker take the job from queue, process it, send it to a result queue, which will be consumed by the web server, then web server send it to clients via websocket. In this case the client doesn't have to.

Which of these are mostly common used? Or are there better solutions?

like image 820
swang Avatar asked Dec 07 '25 09:12

swang


1 Answers

  1. Worker take the job from queue, process it, save the result for client to poll. So there is no communication between the web server and worker

This is rare because typically, the client communicates only with the web server. So, unless you are going to also make easy worker be a web server on some additional port and enable CORS communication with them, this is typically not done.

  1. Worker take the job from queue, process it, send it to a result queue, which will be consumed by the web server(how to do this with express?), then web server sends it back to client. Meanwhile client will be waiting (is this still called a long polling?)

This is relatively common in node.js if you have a compute intensive (e.g. CPU bound) operation because this is one way to allow node.js to scale better when you have compute intensive operations. It is probably more common to use the clustering module and just fire up N identical node.js processes and share the load among them just because that's probably easier to implement than separate worker processes that communicate back the result to the web server.

  1. Web server return a response immediately, push the job to worker queue. Worker take the job from queue, process it, send it to a result queue, which will be consumed by the web server, then web server send it to clients via websocket. In this case the client doesn't have to.

Whether or not you communicate back to the client via a long running HTTP connection or via a webSocket depends upon a bunch of factors. If the compute time is long (e.g. multiple minutes, then you may run into browser timeout issues so it may be simpler to either have the client poll back in several minutes or use the webSocket). I would tend to not use a webSocket if this was the only thing it was being used for. But, if there were other reasons to have a webSocket for pushing notifications from server to client, I'd absolutely use it for this purpose.

Which of these are mostly common used? Or are there better solutions?

Clustering (which matches none of your options) is probably used the most. But, having a pool of worker processes that serve a queue of requests is a common design pattern in node.js if you have a lot of compute-intensive operations.

Keep in mind that if the operation is long running just because things like multiple database operations take awhile to complete, but these are mostly asynchronous operations, then you don't necessarily need workers at all. node.js scales just fine to lots of simultaneous connections if each one is just doing a series of asynchronous operations. So, you only typically need to go to clustering or worker processes when you have CPU intensive things to do (things that would block the node.js thread from being able to do anything else while they were running). A series of 20 asynchronous database operations that might take several minutes to complete does not need clustering of the main node.js process or workers in order to scale in node.js. In fact, it probably needs scaling of your database server more than anything else.

So, in order of how common, I'd say you'd see this:

  1. Code with async I/O and you get good scalability for lots of simultaneous requests with a single node.js process.

  2. Use node.js clustering to add a cluster per CPU. This allows to you at least maximize the utilization of your CPU for the CPU bound parts of your operations. You should obviously still code with asynchronous I/O to maximize scalability.

  3. If you have specific operations that are either already implemented in external processes or which are CPU bound, then you can go with the queue and worker architecture. If things are CPU bound and you're using async I/O, then it won't really help to have many more workers than you have CPUs without going to multiple servers.

Whether to communicate back the result as a long running HTTP response or via a webSocket is a completely orthogonal question and depends more on how long the result takes (whether it's practical to use a long running HTTP response), whether you also want to communicate back progress along the way and whether you already have a webSocket connection for other reasons. This part of the question shouldn't drive the other choice about how to implement multiple processes.

like image 167
jfriend00 Avatar answered Dec 10 '25 00:12

jfriend00