22 May, 2012

The Node.js cpu blocking thing

Recently a budding entrepreneur told me they were using CoffeeScript, Node.js and MongoDB to create their server application.  I asked if they were aware that by design Node was single-threaded, so the server would block on cpu intensive code. The response was a puzzled look followed by some mumbling about how Node doesn't block because it uses an event loop and asynchronous callbacks.

This reminded me of Ted Dziuba's highly inflammatory post Node.js is Cancer where many on HackerNews completely missed the issues raised. With JGC's recent benchmarking adventure To boldly Go where Node man has gone before, and history somewhat repeating itself in the HackerNews comments, I figured it was time to create my own example to demonstrate that Node.js cpu blocking thing.

Building on previous examples, consider a simple server which upon receiving a request, performs an entirely contrived piece of work (since "fibonacci related benchmarks should die in a fire" :-).

Here's the Go server code:


Here's the Node server code:


To benchmark, we'll run ab on Ubuntu and ask it to connect to the Go (1.0.1) or Node (0.6.18) server running on OS X 10.7.3 with quad-core i7 processor and 4GB ram.  Here are the results of making 1,000 requests.


ab -n 1000 http://192.168.1.111:1337/

Go
Time taken for tests:   54.994 seconds
Requests per second:    18.18 [#/sec]
Time per request:       54.994 [ms]
Transfer rate:          1.70 [Kbytes/sec]


Node
Time taken for tests:   58.182 seconds
Requests per second:    17.19 [#/sec]
Time per request:       58.182 [ms]
Transfer rate:          1.28 [Kbytes/sec]

Let's make another 1,000 requests, this time with 100 concurrent requests.

ab -n 1000 -c 100 http://192.168.1.111:1337/

Go (launched with environment variable GOMAXPROCS=4)
Time taken for tests:   17.416 seconds
Requests per second:    57.42 [#/sec]
Time per request:       17.416 [ms]
Transfer rate:          5.38 [Kbytes/sec]


Node
Time taken for tests:   50.601 seconds
Requests per second:    19.76 [#/sec]
Time per request:       50.601 [ms]
Transfer rate:          1.47 [Kbytes/sec]

As you can see, when requests are sent to the server concurrently, the Go server speeds up dramatically and is much faster than the Node server. It's almost as if the Node server can't handle concurrent requests and is simply processing them one at a time.

So what's happening? Well, for each incoming request, the Go server kicks off a goroutine, which takes advantage of the quad-core processor to perform processing in parallel. Goroutines are presumably multiplexed over multiple OS threads, but that's a runtime implementation detail.  By contrast, the Node server only has a single thread of execution, so the event loop is blocked while it's processing.

If your brain is starting to think about algorithms, real-world latency and optimisation, stop!  The benchmarks don't really matter.  The important thing to take away here is that a Node server's event loop can be easily blocked.  This might come as a shock to some Node beginners but it shouldn't. Quoting from Tom's introductory Node book :
"This single-threaded concept is really important. One of the criticisms leveled at Node.js fairly often is its lack of “concurrency.” That is, it doesn’t use all of the CPUs on a machine to run the JavaScript."
"Because Node relies on an event loop to do its work, there is the danger that the callback of an event in the loop could run for a long time. This means that other users of the process are not going to get their requests met until that long-running event’s callback has concluded." 
"As we’ve mentioned, Node is single-threaded. This means Node is using only one processor to do its work. However, most servers have several “multicore” processors, and a single multicore processor has many processors. A server with two physical CPU sockets might have “24 logical cores”—that is, 24 processors exposed to the operating system. To make the best use of Node, we should use those too. So if we don’t have threads, how do we do that?"
Fortunately, there's no need to fret. To take advantage of multiple processors, simply use a package called Cluster, which forks child processes to run as individual Node servers.  So here's the code for the Node server again, this time using Cluster.


As expected, when four Node servers are launched, the results improve substantially.

ab -n 1000 -c 100 http://192.168.1.111:1337/

Go (launched with environment variable GOMAXPROCS=4)
Time taken for tests:   17.416 seconds
Requests per second:    57.42 [#/sec]
Time per request:       17.416 [ms]
Transfer rate:          5.38 [Kbytes/sec]

Node Cluster (4 servers launched)
Time taken for tests:   26.967 seconds
Requests per second:    37.08 [#/sec]
Time per request:       26.967 [ms]
Transfer rate:          2.75 [Kbytes/sec]

Using Cluster looks simple, but if you're a conscientious programmer, you now have a few things to worry about.  For example "Forking a new worker when a death occurs" or "Monitoring worker health using message passing".  Digging deeper, you might even begin to question the very use of Cluster!  Node add-ons like WebWorkersFiber (non-preemptive scheduling) and Threads a Go Go (real threads) offer alternative approaches. Confused yet?

By contrast, Go has concurrency baked-in. Goroutines and channels provide a simple and elegant approach to writing fast server applications. A single Go server offers a level of concurrency matched only by a cluster of Node servers. There are many reasons to like Go which is why it's my language of choice.

Node is great for Javascript developers but for everyone else there's probably already a comparable solution close to home. As for buzzword entrepreneurs, there are always greener pastures!

24 December, 2011

50% Discount - Happy Holidays!

Here's a crazy holiday offer to go with the eggnog and mince pies!

Use coupon MADSANTA in the Bitcartel Online Store for 50% OFF everything! (Valid 24-26 Dec)

To give a gift, simply use the web store as normal, entering your payment details, but under 'License Options' enter the recipients name. You can then print out and glue the registration code into their Christmas card!



02 December, 2011

PandoraJam - latest info on Twitter feed

Before sending emails to PandoraJam support, please check the following resources.

To get the latest official news about PandoraJam, check the Twitter feed.
http://www.twitter.com/pandorajam

Looking at what others are saying about PandoraJam on Twitter is a useful way to find out about potential problems and solutions.
http://twitter.com/#!/search/%40pandorajam


More answers, tips and helpful information can be found here:
http://support.bitcartel.com/pandorajam

Thank you!

22 September, 2011

Dear PandoraJam Fans...

Update 3 (2 Dec 11) PandoraJam 2 works with Pandora.com's HTML5 player, so this post can be disregarded. If you are using PandoraJam 1.x please upgrade for free to PandoraJam 2.


Update 2 (24 Sep 11) Good news. We've been able to restore most features and continue to make progress. Please keep your PandoraJam updated via the menu option 'Check for Updates...' or download from this link: http://www.bitcartel.com/downloads/pandorajam.zip

Update 1 (22 Sep 11) Some cheerful news! We have released a test version of PandoraJam 2 which has basic support for Pandora.com's new HTML5 player. Please update the app via the menu option 'Check for Updates...'

Dear PandoraJam Fans…

It's probably been coming ever since Pandora announced their new HTML5 player... bad news.

Over the last few weeks we've been working hard at keeping PandoraJam working with Pandora.com's classic Flash player.  In fact, a few more bugs had been fixed and issues resolved this week, and like car enthusiasts, there was some satisfaction in keeping the motor running and tuned up.  In the end though, it never rains, it pours.

This Wednesday evening, PandoraJam was chugging along as usual. Sweet. However as of around midnight EST, it seems Pandora.com turned off the classic Flash version and are now pushing all listeners to use their new HTML5 based player.  A hint of that was detected when earlier in the day it was noticed that a link titled 'Old Site' had been removed from Pandora.com's HTML5 player (they have a minimum browser specification where all browsers support the new player).

Overall, this is great news for Pandora fans as the classic Flash player was resource intensive, but bad news for PandoraJam. The classic Flash player no longer loads.  With the classic Flash player turned off, PandoraJam no longer functions.  Kaput!  We must admit, we're somewhat surprised at how quickly Flash has been removed, as we felt Pandora.com would let listeners who use older operating systems and browsers stick around for say 12 to 18 months (there's little development cost in keeping the old Flash player around), but alas, no.

Thus, sadly, with immediate effect we are temporarily suspending sales of PandoraJam.  Our refund policy is normally 30 days but we're extending it out to Aug 1st (just under two months).  If you need a refund, email support@bitcartel.com (purchases and refunds are processed through FastSpring, our payment processor).  For long-time users, we hope you've had fun and enjoyed zillions of hours of music pleasure, and all for less than the cost of a beer and pizza ;-)
Update: Sales are back online now

Will there be a PandoraJam 2 with HTML5 support?  We don't have an answer at this point but we're working on it. We think it should be possible, we might lose some features, but that will still be better than looking at a blank screen.  If there is a PandoraJam 2, it will be a free upgrade for all users.  We'll keep you posted as to progress (more frequent updates on our twitter feed).
Update: For clarification, we are attempting to restore all features. Note that PandoraJam 2 requires OS X 10.5 or later.

Since the summer of 2007, we've been receiving emails from music fans who found PandoraJam, fell in love with Pandora, and ended up becoming Pandora One subscribers.  It's been quite a journey to watch Pandora, a little startup in Oakland, grow into a publicly listed company on the NASDAQ , and quite remarkable that the Flash based player lasted so long at all.  Now they're all grown up and HTML5... yet with Google Music, iCloud, Spotify, Rdio, Turntable, and others hitting the scene, it's like the internet music party is only just getting started.

Stay wired. Namaste.

15 September, 2011

PandoraJam - Updated for Lion & Classic Pandora

Update: This is a full release, and no longer a beta, so the post has been modified slightly.


There is a new version of PandoraJam (1.7 build 476) available for download:

What's new:


  • supports Classic Flash version of Pandora website (and not the new HTML5 version) and will try to load the Classic Flash version
  • support for Mac OS X 10.7 Lion (requires Mac OS X 10.5 or later)
  • now streams music to AppleTV
  • fixes a problem streaming music to some Airport Express units
  • auto reloads if the app does not launch properly and thus cannot enhance the Pandora website (this means you no longer have to 'Empty Cache', quit and relaunch the app)
  • auto fixing of windowing position (when sometimes Pandora website message banners caused the entire display to be shifted down)

Some help:

You shouldn't need to do anything special... but if PandoraJam does not load the Classic Flash website properly, try the following:
  1. Launch Safari and visit Pandora.com
  2. If you are taken to the new HTML 5 website, click the 'Old Site' link in the top right hand corner
  3. Once the Classic Flash website player loads, close the browser window.
  4. Launch PandoraJam
Bonus:

It seems possible (for now) to run the new HTML 5 player in a browser window logged into one account, while the PandoraJam application uses another account. 



Known issue:

On Mac OS X 10.7 Lion, Adobe Flash Player version 10,3 repeats letter keystrokes. This affects the Flash Player when running in 32 bit mode (which is what PandoraJam runs in), but not in 64 bit mode. Downgrading to Flash Player version 10,2 eliminates the keystroke problem.  This is an Adobe Flash (possibly WebKit) bug and needs to be fixed by Adobe (possibly Apple).

04 August, 2011

PandoraJam - Beta with 10.7 support

There is a new beta of PandoraJam available for download and testing.
Changes include:
  • support for Mac OS X 10.7 Lion (requires Mac OS X 10.5 or later)
  • now streams music to AppleTV
  • fixes a problem streaming music to some Airport Express units
  • auto reloads if the app does not launch properly and thus cannot enhance the Pandora website (this means you no longer have to 'Empty Cache', quit and relaunch the app)
  • auto fixing of windowing position (when sometimes Pandora website message banners caused the entire display to be shifted down)
Known issues:
  • On Mac OS X 10.7 Lion, Adobe Flash Player version 10,3 repeats letter keystrokes. This affects the Flash Player when running in 32 bit mode (which is what PandoraJam runs in), but not in 64 bit mode. Downgrading to Flash Player version 10,2 eliminates the keystroke problem.
Update (6 Aug)
  • Link updated
  • Fixed a problem where CPU usage in previous betas would hit 100%

03 June, 2011

Spare some Bitcoin, sir?

Looking to play around with Bitcoin so get in touch if you want to swap 1 Bitcoin for 1 registration code to any software from Bitcartel!

Here's the bitcoin address:
  • 1EggFpzZUj3wDevgkqVBvPGFu6ocJarQd
Also send an email to support@bitcartel.com with your desired registration name for the software.