Segmentation Fault during high load concurrency test with WebWorker Threads - javascript

So, I'm trying to conduct a test to see how much WebWorker Threads (https://github.com/audreyt/node-webworker-threads) can improve CPU intensive tasks with NodeJS in a multi core system.
I actually got this working on a VM with a single core assigned at work, but when I tried it on my home VM with 4 cores, I'm getting a Segmentation Fault after 15-20 requests.
I've got my project up at https://github.com/WakeskaterX/NodeThreading.git
I have tried eliminating pieces to see why I'm getting the SegFault, but even just returning static numbers throws the SegFault after 15-20 requests.
For the loadtest command I'm running:
loadtest -c 4 -t 20 http://localhost:3030/fib?num=30
It runs just fine when it's synchronously calculating the Fibonacci sequence, but as soon as it hits a web worker it Segmentation Fault Core Dumps. Perhaps this is related to the WebWorker-Threads code on the back end, but I'm mainly wondering why it's happening and how I can debug it further or fix it so I can test background threading in nodejs.

this is a variable lifetime issue — In general, a long-running worker needs to be assigned into an object, instead of a lexical variable; the latter is garbage-collected away when the scope exits.
See https://github.com/WakeskaterX/NodeThreading/pull/1 for the pull request that fixes the issue.

Related

Javascript acting multitheaded in Firefox

Everything relevant on the internet I've read indicates that Javascript is single-threaded (aside from Web Workers, which run in a different global context and shouldn't be able to directly affect the state in the main thread). However, while debugging some code, I noticed that even while I was paused on such-and-such a line, variables kept changing, even when I didn't step over lines of code. Investigating further, I noticed that, again, even while paused in the debugger (and I wasn't touching anything), logs were logged and errors were thrown every second according to a timeout that had been set.
I am using OS: Windows 10 Enterprise, version 1803, OS build 17134.407.
I experienced the issue in Firefox 63.0.1 (64-bit).
When I tried it in Chrome 70.0.3538.102 (Official Build) (64-bit), however, the issue did not occur - pausing in the debugger appeared to pause all computation, as expected.
I can't provide any useful code, because 1. it's company code, and 2. it's a multithreading style problem, which makes it very difficult to narrow down to any given section of code. Things that might be relevant, aside from aforementioned browser differences: it's an AngularJS application, served to the browser from NodeJS. We're using $interval(), timeout(), $http, and Stomp websocket connections.
According to my understanding, this apparently multithreaded behavior should be impossible. How could this happen?
Nodejs in fact is not single threaded. It has basically two parts:
Javascript part. Basically Event loop processes (single threaded).
C++ part (libuv library), thanks to V8. This part implements a thread pool with multiple thread to compute costly operations. This way we don't block the event loop.
So, maybe you can check all the modules that you are using and check their implementation. Anyone implemented in C++ uses the thread pool on the background.

PhantomJS with embedded web server uses only one CPU

I have a problem using PhantomJS with web server module in a multi-threaded way, with concurrent requests.
I am using PhantomJS 2.0 to create highstock graphs on the server-side with Java, as explained here (and the code here).
It works well, and when testing graphs of several sizes, I got results that are pretty consistent, about 0.4 seconds to create a graph.
The code that I linked to was originally published by the highcharts team, and it is also used in their export server at http://export.highcharts.com/. In order to support concurrent requests, it keeps a pool of spawned PhantomJS processes, and basically its model is one phantomjs instance per concurrent request.
I saw that the webserver module supports up to 10 concurrent requests (explained here), so I thought I can tap on that to keep a lesser number of PhantomJS processes in my pool. However, when I tried to utilize more threads, I experienced a linear slow down, as if PhantomJS was using only one CPU. This slow-down is shown as follows (for a single PhantomJS instance):
1 client thread, average request time 0.44 seconds.
2 client threads, average request time 0.76 seconds.
4 client threads, average request time 1.5 seconds.
Is this a known limitation of PhantomJS? Is there a way around it?
(question also posted here)
Is this a known limitation of PhantomJS?
Yes, it is an expected limitation, because PhantomJS uses the same WebKit engine for everything and since JavaScript is single-threaded, this effectively means that every request will be handled one after the other (possibly interlocked), but never at the same time. The average overall time will increase linearly with each client.
The documentation says:
There is currently a limit of 10 concurrent requests; any other requests will be queued up.
There is a difference between the notions of concurrent and parallel requests. Concurrent simply means that the tasks finish non-deterministically. It doesn't mean that the instructions that the tasks are made of are executed in parallel on different (virtual) cores.
Is there a way around it?
Other than running your server tasks through child_process, no. The way JavaScript supports multi-threading is by using Web Workers, but a worker is sandboxed and has no access to require and therefore cannot create pages to do stuff.

Why does web worker performance sharply decline after 30 seconds?

I'm trying to improve the performance of a script when executed in a web worker. It's designed to parse large text files in the browser without crashing. Everything works pretty well, but I notice a severe difference in performance for large files when using a web worker.
So I conducted a simple experiment. I ran the script on the same input twice. The first run executed the script in the main thread of the page (no web workers). Naturally, this causes the page to freeze and become unresponsive. For the second run, I executed the script in a web worker.
Script being executed
Test runner page
For small files in this experiment (< ~100 MB), the performance difference is negligible. However, on large files, parsing takes about 20x longer in the worker thread:
The blue line is expected. It should only take about 11 seconds to parse the file, and the performance is fairly steady:
The red line is the performance inside the web worker. It is much more surprising:
The jagged line for the first 30 seconds is normal (the jag is caused by the slight delay in sending the results to the main thread after every chunk of the file is parsed). However, parsing slows down rather abruptly at 30 seconds. (Note that I'm only ever using a single web worker for the job; never more than one worker thread at a time.)
I've confirmed that the delay is not in sending the results to the main thread with postMessage(). The slowdown is in the tight loop of the parser, which is entirely synchronous. For reasons I can't explain, that loop is drastically slowed down and it gets slower with time after 30 seconds.
But this only happens in a web worker. Running the same code in the main thread, as you've seen above, runs very smoothly and quickly.
Why is this happening? What can I do to improve performance? (I don't expect anyone to fully understand all 1,200+ lines of code in that file. If you do, that's awesome, but I get the feeling this is more related to web workers than my code, since it runs fine in the main thread.)
System: I'm running Chrome 35 on Mac OS 10.9.4 with 16 GB memory; quad-core 2.7 GHz Intel Core i7 with 256 KB L2 cache (per core) and L3 Cache of 6 MB. The file chunks are about 10 MB in size.
Update: Just tried it on Firefox 30 and it did not experience the same slowdown in a worker thread (but it was slower than Chrome when run in the main thread). However, trying the same experiment with an even larger file (about 1 GB) yielded significant slowdown after about 35-40 seconds (it seems).
Tyler Ault suggested one possibility on Google+ that turned out to be very helpful.
He speculated that using FileReaderSync in the worker thread (instead of the plain ol' async FileReader) was not providing an opportunity for garbage collection to happen.
Changing the worker thread to use FileReader asynchronously (which intuitively seems like a performance step backwards) accelerated the process back up to just 37 seconds, right where I would expect it to be.
I haven't heard back from Tyler yet and I'm not entirely sure I understand why garbage collection would be the culprit, but something about FileReaderSync was drastically slowing down the code.
What hardware are you running on? You may be running into cache thrashing problems with your CPU. For example if the CPU cache is 1MB per core (just an example) and you start trying to work with data continually replacing the cache (cache misses) then you will suffer slow downs - this is quite common with MT systems. This is common in IO transfers too. Also these systems tend to have some OS overheads for the thread contexts as well. So if lots of threads are being spawned you may be spending more time managing the contexts than the thread is 'doing work'. I haven't yet looked at your code, so I could be way off - but my guess is on the memory issue just due to what your application is doing. :)
Oh. How to fix. Try making the blocks of execution small single chunks that match the hardware. Minimize the amount of threads in use at once - try to keep them 2-3x the amount of cores you have in the hardware (this really depends what sort of hw you have). Hope that helps.

High CPU Utilization for Meteor.js

A meteor.js 0.82 app is running on an Ubuntu 14.04 server with 2GB memory and 2 cpu cores. It was deployed using mup. However the CPU utilization is very high, htop reports 2.72 load average.
Question: How do I find out which part of the app is causing such a high CPU utilization? I used Kadira but it does not reveal anything taking up alot of CPU load afaik.
Does Meteor only use a single core?
I had a similar problem before with Meteor 0.8.2-0.8.3. Here are what I have done to reduce the CPU usage, hope you may find it useful.
double check your functions, ensure all function has proper return, and does properly catch errors
try to use a replicaSet and oplog mongo convert standalone to replica set
write scripts to auto kill and resprawn a node process if it exceeds 100% cpu usage
utilize multi-core capability by starting 2 processes (edit you have done already) and configure and setup load-balance and reverse proxy
make sure to review your publish and subscription and limit what data to be sent to client (simply avoid something like Collection.find();)
Personally I recommend Phusion Passenger, it makes deploying Meteor applications an ease, and I have used it for several projects without any major problems.
One more thing, avoid running the processes in root (or privilege user), you should be running your apps in another user like www-data. This is for obvious security reason.
P.S. and multiple mongo processes showing in htop are threads under a master process, you can view it in tree mode by pressing F5.

Phantomjs dies by high memory consumption

We are using phantomjs to run our qunit tests page on our TFS build server. Our version of test runner is built from below example
https://github.com/ariya/phantomjs/blob/master/examples/run-qunit.js
Over a period of time number of tests increased from hundreds to couple of thousands and on a fine day phantomjs started crashing. It literally dies saying upload the dump and when you see the dump it 0kb !!
When we took a closer look at it on process explorer we found that memory consumption by phantomjs keeps going up as phantomjs is running tests and eventually crashes somewhere 833MB.
Yes the same amount of memory was being utilized by chrome and IE ! And Yes-Yes our tests were leaking memory :(. We did fixed it, memory utilization is lowered by 50% on chrome and IE and we expected phantomjs will handle it now. But no, phantomjs still kept crashing, process explorer shows same memory consumption.
http://phantomjs.org/api/webpage/method/close.html
According to above documentation phantomjs releases heap allocation just on close ? Could that be the reason why our fixed test consumed less memory on chrome but not phantomjs ? And last how to fix this ? How to make phantomjs keep garbage collecting javascript objects to reduce heap allocation ?
Update 1 - 07/28
We took a work around. I did modified my script to execute my tests module by module. In loop after executing all tests for a module I call page.close so it releases the memory for each module and never keeps building the dead heap of objects. Not closing this question since since its a workaround and not a solution. Hope creators will fix this sometime.
There is a static method, QWebPageSettings::clearMemoryCache, that invokes WebKit's garbage collection. However, it clears all QWebPage memory cache for every instantiated QWebPage object and is therefore, currently, unsuitable for including as an option in PhantomJS.
The Github pull request is available here:
https://github.com/ariya/phantomjs/pull/11511
Here's the Google Groups discussion:
https://groups.google.com/forum/#!msg/phantomjs/wIDp9J7B-bE/v5U31_mTbswJ
Until a workaround is available, you might break up your unit tests into blocks on separate pages. It will take a change to QtWebkit's implementation and how memory/cache is handled across QWebPage objects.
Update September 2014:
https://github.com/ariya/phantomjs/commit/5768b705a0
It looks like support for clearing memory cache was added, but there is a note about my original comment in the commit.
I managed to work around it by setting the /LARGEADDRESSAWARE flag
If you have visual studio installed, run from a visual studio command prompt
editbin /LARGEADDRESSAWARE <pathto>/PhantomJS.exe

Categories

Resources