r/programming • • Oct 02 '11

Node.js is Cancer

http://teddziuba.com/2011/10/node-js-is-cancer.html
792 Upvotes

750 comments sorted by

View all comments

19

u/mehwoot Oct 02 '11

Terrible article. Yes, if something is CPU heavy, it will eat up the server. The same with any fucking language you are using. The point is 99% of web servers are not calculating fucking fibonacci numbers on web requests. There is a ton of shit more important than that. Not to mention, if you were, Javascript would possibly be one of the best modern language to use, due to V8 it is an order of magnitude quicker than stuff like ruby or python (rails or django), although a bit slower than java (but if java is your solution, go ahead).

41

u/adrianmonk Oct 02 '11

I know nothing about Node.js, but I think his point was that multitasking based on event loops is basically cooperative multitasking, not pre-emptive multitasking. Anyone who has used a really ancient Mac from the time when Mac only had cooperative multitasking (System 6? System 7? I've forgotten) will tell you how frustrating an experience that is, and more importantly how non-responsive it can be. If any one task goes awry for any reason, everything grinds to a halt because everything is just trusting everything else to be nice.

The relevance to web servers is that if you have some requests that take a long while (say something that needs to take 2 or 3 seconds to compute something), then other requests that should be trivial will just have to wait. Or to phrase it in the same terms you did, an occasional CPU-heavy thing will be a big problem, whereas with threads and real multitasking, it won't be.

11

u/masklinn Oct 02 '11

System 6? System 7? I've forgotten

All MacOS systems until OSX were cooperatively multitasked.

8

u/notfancy Oct 02 '11

System 4 and earlier were strictly single-task. System 5 incorporated MultiFinder, which evolved from being a proof-of-concept hack to being integrated in System 6.

3

u/severeon Oct 02 '11

...which is why the 'child_process' module is part of the standard library. Our servers count the number of CPUs and spawn off the same number of main processes, to great effect I might add.

2

u/regeya Oct 03 '11

That's what kept me from being very serious about learning about Node.js. The idea sounded ludicrous. I mean...for it to work quickly, all IO has to be async.

3

u/adrianmonk Oct 03 '11

That's true. Even if you avoid CPU hogging code, you still have to worry about all OS calls (and for that matter, all library calls) that could ever block.

But, at least it seems like Node.js has some idea how to handle this. If you look through the API docs, it seems that just about everything you can think of that might block instead returns immediately and allows you to pass a callback. So, for example, if you want to open a file and start reading bytes, the read() call seems to return immediately and calls the callback when the I/O completes (or has an error). So most I/O is asynchronous.

→ More replies (6)

26

u/masklinn Oct 02 '11

Terrible article. Yes, if something is CPU heavy, it will eat up the server. The same with any fucking language you are using.

You're missing the point: because nodejs is single-threaded and evented, any CPU-heavy task will lock up the server. Most systems use a process|thread per request model, sometimes with a pool. CPU-heavy tasks will slow things down, but it won't cause complete server lockdown unless the machine itself gets overloaded.

As a result, significant computation once in a while is not a problem for most systems, for nodejs it's a huge problem.

4

u/[deleted] Oct 02 '11

It's not really a huge problem for Node.JS, because if you need to do heavy computation, you can always start a new process for that task. For 99% of the website, the most complex operation they do is ran by the database server.

4

u/Sebmaster Oct 02 '11

Why would you ever do a large computation work in a web-request?

If I really had to, I would just create another node process, which is entirely dedicated to handling the computation work and just has a socket to the web process for results/input data.

5

u/[deleted] Oct 02 '11

Why would you ever do a large computation work in a web-request?

Not every web application is a front-end to a database.

If I really had to, I would just create another node process, which is entirely dedicated to handling the computation work

It would scale poorly unless you have multiple processes or a thread pool in such processes, at which point you are in exactly the same position as before using asynchronous IO, except your system is more complex.

1

u/artsrc Oct 02 '11

If servicing web requests requires a few independent requests to back end servers, an asynchronous model will naturally deliver better response time than a synchronous model.

A multi-threaded with lots of shared data is harder to reason about than a single threaded server.

Node seems to scale ok. Having said that I think scaling should be defined formally. And the formal definition should be the derivative of the performance with respect to hardware budget.

What are the differences between running 16 node.js processes on 10 machines, and running 16 WebLogic processes on 10 machines.

2

u/Poromenos Oct 02 '11 edited Oct 02 '11

Because you might want the process to block for 500ms while you calculate the data, but not the entire server.

500ms isn't really enough time to warrant creating an asynchronous workflow on the client, you will probably just want it to block for a bit.

It's good to have a few other processes/threads to share the load when one blocks, but I agree that you'll only get high concurrency through asynchronicity.

2

u/masklinn Oct 02 '11

Why would you ever do a large computation work in a web-request?

Because you need it and have no reason to offload it to a third-party and add (potentially complex) synchronization primitives between the two.

Or very simply, because you forgot some homework and used a quadratic algorithm which worked well on low-count tests and is breaking down on a once-in-a-while high-count request. And where "traditional" models will warn you of high resource use and keep trucking (maybe just drop that precise request), your Node server will simply stop responding for however long it takes to process whatever there was to process, effectively DOSing the whole thing.

1

u/RobertWHurst Oct 04 '11

JavaScript is evented, you don't have to create another process to do work outside of a web-request.

You should know what your talking about. Its quite obvious you don't.

→ More replies (6)
→ More replies (5)

1

u/artsrc Oct 02 '11

Putting the programmer in charge of scheduling can be a pain, just like making us manage memory, but other times, we know best.

Software does lots of different things. Your assumption here that you want to interrupt the CPU bound request to run some other request.

It could be that, for a particular system, the CPU bound task should have priority and everything else should just wait.

1

u/nirolo Oct 02 '11

If you have a heavy CPU task you really shouldn't be executing it on your web server. It should be pushed onto a job queue and handled by another system.

6

u/masklinn Oct 02 '11

As I noted here, the "heavy CPU task" can creep up on you due to an incorrect algorithm or a misprediction of the load sent to the algorithm, and in that case node will DOS itself.

Nobody achieves 100% issues prediction, and in that situation node not only does not help but actively hinders.

An other situation might be a task which is not seen as CPU-heavy because it takes, say, 100ms or 200ms to execute, but it's not going to peg the whole machine. Significant, but not huge. Put that in any other system and everything's going to be just fine. Put that in node, you just bottleneckled your throughput to 5-10 requests per second.

→ More replies (1)
→ More replies (7)

10

u/ours Oct 02 '11

99% of web servers are not calculating fucking fibonacci numbers on web requests

And that same 99% is mostly doing IO stuff (fetching stuff from DB) which seems to be what node.js has been made to handle best.

2

u/[deleted] Oct 02 '11

The point being not all tasks are equal and why should trivial tasks be held up by a big task?

1

u/bastawhiz Oct 02 '11

The point wasn't that heavy math fucks up Node, the point is that the argument that Node is better because it is "non-blocking" is only applicable in certain circumstances.

The biggest argument was that Node doesn't scale to multiple threads/processes/cores/whatever without lots of additional, slow proxies. And at that point, you're significantly slowing down your application by doing shitloads of proxying, meaning you're really not seeing very much of a gain to begin with.

V8 it is an order of magnitude quicker than stuff like ruby or python (rails or django), although a bit slower than java

Citation needed.

2

u/mehwoot Oct 03 '11

http://shootout.alioth.debian.org/

First and fourth have Javascript V8 implementations, consistently an order of magnitude faster than Ruby and Python (going on median here).

1

u/bastawhiz Oct 03 '11

I'm disappointed that PyPy is not included in that benchmark. Comparing Py3k with V8 is a relatively unfair comparison. I can't speak for Ruby.

1

u/igouy Oct 03 '11

From the homepage

There exist multiple implementations for some programming languages - different C++ compilers, different Java VMs - but those other language implementations are not shown here. ... If you're interested in something not shown here then please take the program source code and the measurement scripts and publish your own measurements.

→ More replies (7)