How would I detect infinite loops in Node.js? - node.js

I have a NodeJS app that seems to have an infinite loop due to persistent 100% CPU usage - https://github.com/3PG/Bot.
IDE: VSCode
I have changed many files and lines of code since June, but the problem still persists. I believe it is caused by an infinite loop.
How would I detect infinite loops in Node.js for TypeScript project?

I tried setting up your bot to try and replicate the situation. I disabled the API Module, XP Module, Bot Stats module and Music Module so that I could easily set it up without having to do much configuration. As you can see here, I can't replicate your situation as the Bot is running and it's using 0% of the CPU. It may have to do with the specs of your PC, but I can't replicate, so what I suggest to do is try and disabling various modules, so that you can find the one that's causing the CPU to burst.
I hope I helped you ;)

Related

Debugging an Out of Memory Error in Node.js

I'm currently working on a Node.js project and my server keeps running out of memory. It has happened 4 times in the last 2 weeks, usually after about 10,000 requests. This project is live and has real users.
I am using
NodeJS 16
Google Cloud Platform's App Engine (instances have 2048mb of memory)
Express as my server framework
TypeORM as database ORM (database is postgres hosted on separate GCP SQL instance)
I have installed the GCP profiling tools and have captured the app running out of memory, but I'm not quite sure how to use the results. It almost looks like there is a memory leak in the _handleDataRow function within the pg client library. I am currently using version 8.8.0 of the library (8.9.0 was just released a few weeks ago and doesn't mention fixing any memory leaks in the release notes).
I'm a bit stuck with what I should do at this point.
Any suggestions or advice would be greatly appreciated! Thanks.
Update: I have also cross-posted to reddit and someone there helped me determine that issue is related to large queries with many joins. I was able to reproduce the issue, and will report back here once I am able to solve it.
When using App Engine, a great place to start looking for "why" a problem occurred in your app is through the Logs Explorer. Particularly, if you know the time-frame of when the issues started escalating or when the crash occurred.
Although based on your Memory Usage graph, it's a slow leak. So a top-to-bottom approach of your back-end is really necessary to try and pin-point the culprit. I would go through the whole stack and look for things like Globals that are set and not cleaned up, promises that are not being returned, large result-sets from the database that are bottle-necking the server, perhaps from a scheduled task.
Looking at the 2pm - 2:45pm range on the right-hand of the graph, I would narrow the Logs Explorer down to that exact time-frame. Then I would look for the processes or endpoints that are being utilized most frequently in that time-frame as well as the ones that are taking the most memory to get a good starting point.

node.js hangs other programs on my mac

I'm relatively new to Node and javascript. I'm running a program that does heavy network api calls and process the results. What I'm experiencing is that my node code is making other programs running on my mac (Outlook, Chrome, etc.) unresponsive to the point I can't even force quit those programs and have to hard reboot my machine.
Any idea why that's happening? I thought node.js is somewhat sandboxed and shouldn't affect other programs. Is it node using up all sockets available?
seems I've found the reason for node.js itself to use a lot of CPU and memory. I have some code processing thousands rows of user location and calculating the distances. That seems to be very expensive and have a big toll on node. I've moved that code into process.nextTick() and it's not hanging other programs any more.
What I still don't understand is that why node hangs, why it hangs up other programs on my mac as well.

Node.js require becomes extremely slow after OS X has been running for a while

When I reboot my Mac, starting up Node.js apps is nice and fast. Later, after the Mac has been on for a few hours, it gets REALLY slow.
I've used process.hrtime() to time various things, and it seems that it's all the require calls that take time, ie loading dependencies. Once everything is loaded, my apps run reasonably fast.
The difference is extreme: just after I've rebooted, an app may take 300ms to get through the require calls, then it takes something like 30 seconds once it's been on for a few hours.
What could be causing this?
Since how fast executing require is perfectly related to a disk loading performance.
So I suppose It's highly possible that HDD/SSD or whatever your project belongs causing that.
it's working fine right after you rebooted so maybe some background software(such as virus scan or auto downloader) is making IO blocking
You'd better start by checking your CPU/RAM/HDD status while the issue is occurring and see what happens if you move your project into USB flash drive or external HDD

Node.js app has periodic slowness and/or timeouts (does not accept incoming requests)

This problem is killing the stability of my production servers.
To recap, the basic idea is that my node server(s) sometimes intermittently slow down, sometimes resulting in Gateway Timeouts. As best as I can tell from my logs, something is blocking the node thread (meaning that the incoming request is not accepted), but I cannot for the life of me figure out what.
The problem ranges in severity. Sometimes what should be <100ms requests take ~10 seconds to complete; sometimes they never even get accepted by the node server at all. In short, it is as though some random task is working and blocking the node thread for a period of time, thus slowing down (or even blocking) incoming requests; the one thing I can say for sure is that the need-to-fix-symptom is a "Gateway Timeout".
The issue comes and goes without warning. I have not been able to correlate it against CPU usage, RAM usage, uptime, or any other relevant statistic. I've seen the servers handle a large load fine, and then have this error with a small load, so it does not even appear to be load-related. It is not unusual to see the error around 1am PST, which is the smallest load time of the day! Restarting the node app does seem to maybe make the problem go away for a while, but that really doesn't tell me much. I do wonder if it might be a bug in node.js... not very comforting, considering it is killing my production servers.
The first thing I did was to make sure I had upgraded node.js to the latest (0.8.12), as well as all my modules (here they are). Of course, I also have plenty of error catchers in place. I'm not doing anything funky like printing out lots to the console or writing to lots of files.
At first, I thought it was outbound HTTP requests blocking the incoming socket, because the express middleware was not even picking up the inbound request, but I gave up the theory because it looks like the node thread itself became busy.
Next, I went through all my code with JSHint and fixed literally every single warning, including a few accidental globals (forgetting to write "var") but this didn't help
After that, I assumed that perhaps I was running out of memory. But, my heap snapshots via nodetime are looking pretty good now (described below).
Still thinking that memory might be an issue, I took a look at garbage collection. I enabled the --nouse-idle-notification flag and did some more code optimization to NULL objects when they were not needed.
Still convinced that memory was the issue, I added the --expose-gc flag and executed the gc(); command every minute. This did not change anything, except to occasionally make requests a bit slower perhaps.
In a desperate attempt, I setup the "cluster" module to use 2 workers and automatically restart them every 30 min. Still, no luck.
I increased the ulimit to over 10,000 and kept an eye on the open files. There seem to be < 300 open files (or sockets) per node.js app, and increasing the ulimit thus had no impact.
I've been logging my server with nodetime and here's the jist of it:
CentOS 5.2 running on the Amazon Cloud (m1.large instance)
Greater than 5000 MB free memory at all times
Less than 150 MB heap size at all times
CPU usage is less than 60% at all times
I've also checked my MongoDB servers, which have <5% CPU usage and no requests are taking > 100ms to complete, so I highly doubt there's a bottleneck.
I've wrapped (almost) all my code using Q-promises (see code sample), and of course have avoided Sync() calls like the plague. I've tried to replicate the issue on my testing server (OSX), but have had little luck. Of course, this may be just because the production servers are being used by so many people in so many unpredictable ways that I simply cannot replicate via stress tests...
Many months after I first asked this question, I found the answer.
In a nutshell, the problem was that I was not piping a big asset when transferring it from one server to another. In other words, I was downloading an image from one server, before uploading it to a S3 bucket. Instead of streaming the download into the upload, I downloaded the file into memory, and then uploaded it.
I'm not sure why this did not show up as a memory spike, or elsewhere in my statistics.
My guess is Mongoose. If you are storing large payloads in Mongo, Mongoose can be pretty slow due to how it builds the Mongoose objects. See https://github.com/LearnBoost/mongoose/issues/950 for more details on the problem. If this is the problem you wouldn't see it in Mongo itself since the query returns quickly, but object instantiation could take 75x the query time.
Try setting up timers around (process.hrtime()) before and after you the Mongoose objects are being created to see if that might be the problem. If this is the problem, I would switch to using the node Mongo driver directly instead of going through Mongoose.
You are heavily leaking memory, try setting every object to null as soon as you don't need it anymore! Read this.
More information about hunting down memory leaks can be found here.
Give special attention to having multiple references to the same object and check if you have circular references, those are a pain to debug but will help you very much.
Try invoking the garbage collector manually every minute or so (I don't know if you can do this in node.js cause I'm more of a c++ and php coder). From my years of experience working with c++ I can tell you the most likely cause of your application slowing down over time is memory leaks, find them and plug them, you'll be ok!
Also assuming you're not caching and/or processing images, audio or video in memory or anything like that 150M heap is a lot! Those could be hundreds of thousands or even millions of small objects.
You don't have to be running out of memory for your application to slow down... just searching for free memory with that many objects already allocated is a huge job for the memory allocator, it takes a lot of time to allocate each new object and as you leak more and more memory that time only increases.
Is "--nouse-idle-connection" a mistake? do you really mean "--nouse_idle_notification".
I think it's maybe some issues about gc with too many tiny objects.
node is single process, so watch the most busy cpu core is much important than the load.
when your program is slow, you can execute "gdb node pid" and "bt" to see what node is busy doing.
What I'd do is set up a parallel node instance on the same server with some kind of echo service and test that one. If it runs fine, you narrow down your problem to your program code (and not a scheduler/OS-level problem). Then, step by step, include the modules and test again. Certainly this is a lot of work, takes long and I dont know if it is doable on your system.
If you need to get this working now, you can go the NASA redundancy route:
Bring up a second copy of your production servers, and put a proxy in front of them which routes each request to both stacks and returns the first response. I don't recommend this as a perfect long-term solution but it should help significantly reduce issues in production now, and help you gather log data that you could replay to recreate the issues on non-production servers.
Obviously, this is straight-forward for read requests, but more complex for commands which write to the db.
We have a similar problem with our Node.js server. It didn't scale well for weeks and we had tried almost everything as you had. Our problem was in the implicit backlog value which is set very low for high-concurrent environments.
http://nodejs.org/api/http.html#http_server_listen_port_hostname_backlog_callback
Setting the backlog to a significantly higher value (e.g. 10000) as well as tune networking in our kernel (/etc/sysctl.conf on Linux) as described in manual section helped a lot. From this time forward we don't have any timeouts in our Node.js server.

MonoTouch Running differently on IOS Emulator than on IPad

I'm having issues around my app (basically a modified Mobile World Conference) app when I run it on the IOS Emulator in windows, verses running it directly on the IPad itself. I understand that there is a different process or involved so I don't expect it to be exactly the same.
In specific, I'm getting errors around initializing sql databases (SqlLite) with errors being
"Object Not Defined"
When I try and single step debug to the device, I get errors that feel like somehow the stack has been corrupted and I can not even debug into methods.
My question is, what are the types of differences I can look for and how to debug them? There must be some pattern of things that cause issues, I just have no idea what that is or how to figure it out. I'm use to my c# code just working on x86.
What causes simulator to behave differently? Simulator is not constrained in memory usage like a real device so you're likely to hit memory warnings on the device (and crash if you don't handle them properly). The code itself, however, runs faster so race conditions between threads are more likely, so watch out for that. Don't talk to database from different threads, or at least use proper locking. And of course there are AOT limitations which occur only on the device. Your LINQ problem sounds like a AOT problem to me.

Resources