I am currently using cluster in my node.js application but have a bit of confusion on gracefully exiting the server.
Previously I was using just a single process, so in the 'uncaughtException' handler I call server.close(), which stops all incoming requests, then I also set up a timer for about 10 seconds, after that I call process.exit() to kill the server.
Now with cluster, each child process is created with an IPC channel, and calling process.disconnect() seems to do exactly the same thing as what I described for the single node process.
My question is, when using cluster and if I want to gracefully exit the service, what should I do? seems like process.disconnect() is good enough?
Related
Golang developer here, trying to learn JS (Node.js).
I'm used to working with goroutines in Go, which for the sake of simplicity let's assume are just threads (actually they're not exactly threads, more like Green Threads, but bear with me!).
Imagine now that I want to create some kind of service that can run some endlessTask which, for example, could be a function that receives data from a websocket and keeps an internal state updated, which can be queried later on. Now, I want to be able to serve multiple users at the same time and each of them can also stop their specific ongoing task at some point. In Go, I could just spawn a goroutine for my endlessTask, store some kind of session in the request dispatcher to keep track to which user each task belongs.
How can I implement something like this in JS? I looked through Node.js API documentation and I found some interesting things:
Cluster: doesn't seem to be exactly what I'm looking for
Child processes: could work, but I'd be spawning 1 process per client/user and the overhead would be huge I think
Worker threads: that's more like it, but the documentation states that they "are useful for performing CPU-intensive JavaScript operations" and "Node.js built-in asynchronous I/O operations are more efficient than Workers can be"
I'm not sure how I could handle this scenario without multi-threading or multi-processing. Would the worker threads solution be viable in this case?
Any input or suggestion would be appreciated. Thanks!
Imagine now that I want to create some kind of service that can run some endlessTask which, for example, could be a function that receives data from a websocket and keeps an internal state updated
So, rather than threads, you need to be thinking in terms of events and event handlers since that's the core of the nodejs architecture, particularly for I/O. So, if you want to be able to read incoming webSocket data and update some internal state when it arrives, all you do is set up an event handler for the incoming webSocket data. That event handler will then get called any time there's data waiting to be read and the interpreter is back to the event loop.
You don't have to create any thread structure for that or any type of loop or anything like that. Just add the right event handler and let it call you when there's incoming data available.
Now, I want to be able to serve multiple users at the same time and each of them can also stop their specific ongoing task at some point.
Just add an event listener to each webSocket and your nodejs server will easily serve multiple users. When the user disconnects their webSocket, the listener automatically goes away with it. There's nothing else to do or cleanup in that regard unless you want to update the internal state, in which case you can also listen for the disconnect event.
In Go, I could just spawn a goroutine for my endlessTask, store some kind of session in the request dispatcher to keep track to which user each task belongs.
I don't know goroutines but there are lots of options for storing the user state. If it's just info that you need to be able to get to when you already have the webSocket and don't need it to persist beyond that, then you can just add the state directly to the webSocket object. That object will be available anytime you get a webSocket event so you can always have it there to update when there's incoming data. You can also put the state other places (a database, Map object that's indexed by socket or by username of by whatever you need to be able to look it up by) - it really depends what exactly the state is.
I'm not sure how I could handle this scenario without multi-threading or multi-processing. Would the worker threads solution be viable in this case?
What you have described doesn't sound like anything that would require clustering, child processes or worker threads unless something you're doing with the data is CPU intensive. Just using event listeners for incoming data on each webSocket will let nodejs' very efficient and asynchronous I/O handling kick into gear. This is one of the things it is best at.
Keep in mind that I/O in nodejs may be a little inside-out from one what you're used to. You don't create a blocking read loop waiting for incoming data on the webSocket. Instead, you just set up an event listener for incoming data and it will call you when incoming data is available.
The time you would involve clustering, child processes or Worker Threads are when you have more CPU processing in your Javascript to process the incoming data than a single core can handle. I would only go there if/when you've proven you have a scalability issue with the CPU usage in your nodejs server. Then, you'd want to pursue an archicture that adds just a few other processes or threads to share the load (not one per connection). If you have specific CPU heavy processes (custom encryption or compresssion are classic examples), then it you may help to create a few other processes or Worker Threads that just handle a work queue for the CPU-heavy work. Or if it's just increasing the overall CPU cycles available to process incoming data, then you would probably go to clustering and just let each incoming webSocket get assigned to a cluster and still use the same event handling logic previously described, but now you have the webSockets split across several processes so you have more CPU to throw at them.
I am trying a TCP/IP socket communication between my nodeJS server to an external legacy JAVA application in a request/response mode where nodeJS is a socket client and external application is socket server. I am using promises to wait for the response from server after making a request from my NodeJS client in a periodic cycle in an infinite loop.
This works fine for some time but gives warning after some time saying number of maximum listeners exceeded in nodeJS. I can suppress this warning by increasing max number of listeners in nodeJS, but is it right to do so? I think this will eventually lead to memory leaks. I guess this is happening because each promise call creates an event listener which is never removed and when I call promise function in a loop this will keep on growing the number of listeners!
So my question is:
Is there a way to remove listener created by a promise call after it has been called once?
Is it safe to ignore the warning and let the execution proceed even if its in a never ending loop?
Will replacing promise with async/await help? I guess it may not as this also will add a new listener for each await call.
Do you have any suggestions or solutions? There are no synchronous socket calls in nodeJS as far as I know.
I'm planning on building some backend logic on a server for personal use. Its connected to a websocket from another server and I've set code to handle data from that socket. I'm still fairly new to using websockets so the whole concept is still a little foreign to me.
If I allowed more users to use that backend and the websocket has specific logic running wouldn't it be conflicted by multiple users? Or would each user have their own instance of the script running?
Does it make any sense of what I'm trying to ask?
If I allowed more users to use that backend and the websocket has specific logic running wouldn't it be conflicted by multiple users? Or would each user have their own instance of the script running?
In node.js, there is only one copy of the script running (unless you use something like clustering to run a copy of the script for each core, which it does not sound like you are asking about). So, if you have multiple webSocket connections to the same server, they will all be running in the same server code with the same variables, etc... This is how node.js works. One running Javascript engine and one code base serves many connections.
node.js is an event-driven system so it will serve an incoming event from one webSocket, then return control back to the Javascript system and serve the next event in the event queue and so on. Whenever a request handler calls some asynchronous operation and waits for a response, that is an opportunity for another event to be pulled from the incoming event queue and another request handler can run. In this way, multiple requests handlers can be interleaved with all making progress toward completion, even though there is only one single thread of Javascript running.
What this architecture generally means is that you never want to put request-specific state in the global or module scope because those scopes are shared by all request handlers. Instead, the state should be in the request-specific scope or in a session that is bound to that particular user.
Is it conflicting for multiple users on one backend server websockets
No, it will not conflict if you write your server code properly. Yes, it will conflict if you write your server code wrongly.
i am running a nodejs code (server.js) as a jxcore using
jx mt-keep:4 server.js
we have a lot of request hit per seconds and mostly transaction take place.
I am looking for a way to catch error incase any thread dies and the request information is
returned back to me so that i can catch that request and take appropriate action based on it.
So in this i might not lose teh request coming in and would handle it.
This is a nodejs project and due to project urgency has been moved to jxcore.
Please let me know if there is a way to handle it even from code level.
Actually it's similar to a single Node.JS instance. You have same tools and options for handling the errors.
Besides, JXcore thread warns the task queue when it catches an unexpected exception on the JS land (Task queue stops sending the requests back to this instance) then safely restarts the particular thread. You may listen to 'uncaught exception', 'restart' events for the thread and manage a softer restart.
process.on('restart', res_cb, exit_code){
// thread needs a restart (due to unhandled exception, IO, hardware etc..)
// prepare your app for this thread's restart
// call res_cb(exit_code) for restart.
});
Note: JXcore expects the application is up and running at least for 5 seconds before restarting any thread. Perhaps this limitation protects the application from looping thread restarts.
You may start your application using 'jx monitor' it supports multi thread and reloads the crashed processes.
Is there a way I can make nodejs reload everytime it serves a page?
I want to do this during the dev cycle so I can avoid having to shutdown & startup on each code change?
Edit: Try nodules and their require.reloadable() function.
My former answer was about why not to reload the process of Node.js and does not really apply here. But I think it is still important, so I leave it here.
Node.js is evented IO and crafted specifically to avoid multiple threads or processes. The famous C10k problem asks how to serve 10 thousand clients simultaneously. This is where threads don't work very well. Node.js can serve 10 thousand clients with only one thread. If you were to restart Node.js each time you would severely cripple Node.js.
What does evented IO mean?
To take your example: serving a page. Each time Node.js is about to serve a page, a callback is called by the event loop. The event loop is inherent to each Node.js application and starts running after initializations have completed. Node.js on the server-side works exactly like client-side Javascript in the browser. Whenever an event (mouse-click, timeout, etc.) happens, a callback - an event handler - is called.
And on the server side? Let's have a look at a simple HTTP server (source code example taken from Node.js documentation)
var http = require('http');
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World\n');
}).listen(8124);
console.log('Server running at http://127.0.0.1:8124/');
This first loads the http module, then creates an HTTP server and tells it to invoke the inner function starting with function (request, response) every time an HTTP request comes in, then makes the server listen to port 8124. This completes almost immediately so that console.log will be executed thereafter.
Now Node.js event loop takes over. The application does not end but waits for requests. And voilĂ each request is answered with Hello World\n.
In a summary, don't restart Node.js, but let its event loop decide when your code has to be run.
Found Nodemon, exactly what I wanted: https://github.com/remy/nodemon
I personnaly use spark2 (the fork) and will switch to cluster as soon as i found the time to test it. Among other things, those 2 will listen to file changes and reload the server when appropriate, which seems to be what you're looking for.
There are many apps for doing this, but I think the best is Cluster, since you have 0 downtime for your server. You can also set multiple workers with it or manually start/stop/restart/show stats with the cli REPL functionality.
No. Node.js should always run. I think you may have misunderstood the concept of nodejs. In order for nodejs to serve pages, it has to be its own server. Once you start a server instance and start listening on ports, it will run until you close it.
Is it possible that you've called a function to close the server instead of just closing a given stream?