Hacker News new | ask | show | jobs
by woola 4482 days ago
Having written nodejs for about an year I would never choose it again if I have given the choice.

* No Error handling. The process has to be restarted if something goes wrong.

* No thread local storage equivalent. As a result you can't do simple thing like differentiate log originated from different http requests.

* Callback makes the code unreadable

* Javascript has no real method or in other words 'this' is not attached to a function and is determined by way the function is called. So you have to wrap most of the callbacks with _.bind()

* Mixing callback, promise and event emitter api introduce lot of boilerplate code.

* No stacktrace. Debugging error is PITA

* No preemptive scheduling. So you have to be extra careful that you never spend too much CPU time.

* No easy way to handle back pressure.

1 comments

These are exactly the reasons I have stayed away from it until now. I don't understand this one though, what does it mean?

* No easy way to handle back pressure.

I did some Googling. "back pressure" in the Node context is basically what most people refer to as "flow control" or "overload behavior". Node programs work by enqueueing a bunch of work items for the event loop to handle, and then going on and doing a bunch more stuff until all the work items have been handled and their callbacks have been called. In the process, those callbacks may themselves enqueue further work items.

The problem is that all these callbacks themselves take up memory and hold onto references in the V8 heap. And so if callbacks are being enqueued faster than they can be processed, the heap will get more full. V8's GC takes time proportional to the amount of live data, and so GCs will become more frequent and take longer. This further reduces the amount of available CPU time to process callbacks, which increases the amount of live data, until the system thrashes to a halt.

Haskell programmers (who use a similar scheduling mechanism for lazy evaluation) call this a "space leak", and it's a big problem in Haskell as well. The solution is for the runtime to let the calling code know that it's overloaded, and then either temporarily block the calling code from creating more callbacks until existing ones have run, or let the calling code gracefully degrade and choose to handle things in a simpler fashion.

I see, the tomcat tcp connection backlog is a similar concept I guess, just thats it blocks at some point once the queue is full, unlike node.js?
Latest developments of Node Streams begin to address back pressure.