Promises and async/await in an infinite loop in node.js - javascript

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.

Related

server.close() vs process.disconnect()

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?

Why does performance degrade when a serverless function exits without completing Promise.all() successfully in Firebase Cloud Function?

Why does performance degrade when a serverless function exits without completing Promise.all() successfully in Firebase Cloud Function?
In the past, I used to run Promise.all() without await in Cloud Function.
Then, this would cause the Cloud Function to exit without waiting for Promise.all() to complete.
As a result, my Cloud Function sometimes worked correctly and sometimes did not.
This is problem, so we fixed it to await Promise.all() to wait for all the processing to finish.
Then, the Cloud Function, which used to take several minutes to complete, now completes in a few seconds.
I am curious about this issue and would like to understand it.
Why is it that when I fix all async process to wait, the function completes immediately?
Thanks.
It's simply the serverless model of Google Cloud. You pay when you process traffic, I mean, when your request is handled.
When you have sent a response, you stop to pay, and so, Google limit the CPU available to your Cloud Functions (about 5% of the CPU available). Indeed, if you don't pay, Google threshold the CPU and propose the processing power to other Cloud Function that handle traffic, and which pays for it.
To free the memory reserved by your cloud functions, after a while (about 15 minutes) Google stop the instance.
So, in your case, if you send the response before the end of the processing, the processing will continue in background with a low percentage of CPU. Either it finishes or it doesn't have the time to finish before the instance stop;
Now, because you await all the promises before sending the response, you have 100% of the CPU power for you (because you pay for it) and you finish quickly the processing.

What happens if all node.js's worker threads are busy

I try to understand how node.js works and although I have read this article: When is the thread pool used? I am not sure what happens if all worker threads are busy and another async I/O operation is ready to be executed.
If I got this http://www.future-processing.pl/blog/on-problems-with-threads-in-node-js/ article right, the event loop is blocked until a worker thread is free to take care of an additional I/O operation. This would imply that if five users tried to access a webpage simultaneously (like their profile page which lets say requires a db-query), the 5th user will be blocked until the first db-query is done and this worker thread is free again?
I/O in general does not block the event loop (there are some exceptions like the crypto module currently and things like fs.*Sync() methods) and especially in the case of network I/O, the libuv thread pool is not used at all (only for things like dns (currently) and fs operations).
If your database driver is written in C++ as a node.js addon, there is a chance that it could either block the event loop (it's doing something synchronous) or it could be using the libuv thread pool. However if the database driver is only written in JavaScript, it typically uses some sort of network I/O, which as previously mentioned does not block anything and does not use the libuv thread pool.
So with your example, depending on how the database driver is implemented, all 5 users could be serviced at once. For example, MySQL at the protocol level only supports one outstanding query at a time per connection. So what most MySQL drivers for node.js will do is queue up additional queries until the current query has finished. However, it's entirely possible for a MySQL driver to internally maintain some sort of connection pool so that you have greater concurrency.
However, if each of the 5 requests were instead causing something to be from disk, then it's possible that the 5th request will have to wait until one of the other 4 fs requests have finished, due to the current default size of the libuv thread pool. This doesn't mean the event loop itself is blocked, as it can still service new incoming requests and other things, but the 5th client will just have to wait a bit longer.
Is there any kind of queue for operations which are carried out in worker threads?
Yes. libuv manages this queue. It is possible for all of the worker threads to be occupied, in which case new asynchronous requests that go to the worker pool will not make progress. Note that an "asynchronous FS request" must still be completed somewhere, and will block the worker thread on which it is being handled until it completes.

NodeJS Event Loop Fundamendals

I'm sure it's a commonly asked question but didn't find a concrete answer.
I kind of understand the basic concept of NodeJS and it's asynchronous/non-blocking nature of processing I/O.
For argument sake, let's take a simple example of a HTTP server written in node that executes the unix command 'find /' and writes the result to the http response (therefore displaying the result of the command on the user's browser).
Let's assume that this takes 3 seconds.
Let's assume that there are two users 'A' and 'B' requesting through their browsers exactly at the same time.
As I understand the user's requests are queued in the event queue (Message A, Message B). The message also has a reference to it's associated callback to be executed once the processing is done.
Since, the event loop is single threaded and processes the events one by one,
In my above example, Will it take 6 seconds for the Callback of "User B" to get triggered? [3 for "User A"s event processing and 3 for it's own event processing]
This sounds like I'm missing something here?
The worst is if 100 users are requesting at the same millisecond? The 100th event owner is going to be the most unfortunate user and has to wait for eternity.
As I understand, there is only one event queue in the runtime, the above problem can applicable to any user in any part of the application. For example, a slow Database Query in web page X would slow down the a different user in web page Y?
Fundamentally, I see a problem in serial processing of events and serial execution of their associated callbacks.
Am I missing something here?
A properly written node.js server will use async I/O and communication for any networking, disk I/O, timers or communication with other processes. When written this way, multiple http requests can be worked on in parallel. Though the node.js code that processes any given request is only run one at a time, anytime one request is waiting for I/O (which is typically much of the time of a request), then other requests can run.
The end result is that all requests appear to progress at the same time (though in reality, the work on them is interwoven). The Javascript event queue is the mechanism for serializing the work among all the various requests. Whenever an async operation finishes it's work or wishes to notify the main JS thread of some event, it puts something in the event queue. When the current thread of JS execution finishes (even if it has its own async operations in progress), the JS engine looks in the event queue and then executes the next item in that queue (usually some form of a callback) and, in that way, the next queued operation proceeds.
In your specific example, when you fire up another process and then asynchronously wait for its result, the current thread of execution finishes and then the next item in the event queue gets to run. If that next item is another http request, then that request starts processing. When this second request, then hits some async point, it's thread of execution finishes and again the next item in the event queue runs. In this way, new http requests get started and asynchronous callbacks from async operations that have finished get to run. Things happen in roughly a FIFO (first-in, first-out) order for how they are put in the event queue. I say "roughly" because there are actually different types of events and not all are serialized equally, but for the purpose of this discussion that implementation detail can be ignored.
So, if three http requests arrive at the exact same time, then one will run until it hits an async point. Then, the next will run until it hits an async point. Then, the third will run until it hits an async point. Then, whichever request finishes its first async operation will get a callback from that async operation and it will run until it is done or hits another async point. And, so on...
Since much of what usually causes a web server to take much time to respond is usually some sort of I/O operation (disk or networking) which can all be programmed asynchronously in node.js, this whole process generally works quite well and its actually a lot more efficient with server resources than using a separate thread per request. The one time that it doesn't work very well is if there's a heavy compute-intensive or some long running, but not asynchronous operation that ties up the main node.js thread for long periods of time. Because the node.js system is a cooperative CPU sharing system, if you have a long running operation that ties up the main node.js thread, it will hog the system (there is no pre-emptive sharing at all with other operations like there could be with a mutli-threaded system). Hogging the system makes all other requests wait until the first one is done. The node.js answer to some CPU hogging computation would be to move that one operation to another process and communicate asynchronously with that other process from the node.js thread - thus preserving the async model for the single node.js thread.
For node.js database operations, the database will generally provide an async interface for node.js programming to use the database in an async fashion and then it is up to the implementation of the database interface to actually implement the interface in an async fashion. This will likely be done by communicating with some other process where the actual database logic is implemented (probably communicating via TCP). That actual database logic may use actual threads or not - that's an implementation detail that is up to the database itself. What is important to node.js is that the computation and database work is out of the node.js thread in some other process, perhaps even on another host so it does not block the node.js thread.

Jxcore Error handling in For Multiple Request Nodejs

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.

Categories

Resources