5 ms·
I'm not a node expert, but here is what seems like the crux of the problem: > Consequently, when any request timeouts happened, the event and its associated ca
by skizm 10y ago
I'm not a node expert, but here is what seems like the crux of the problem:
> Consequently, when any request timeouts happened, the event and its associated callback was put on an already overloaded message queue. While the timeout event might occur at 1 second, the callback wasn’t getting processed until all other messages currently on the queue, and their corresponding callback code, were finished executing (potentially seconds later).
Seems pretty specific to node, no? I mean, just looking at what the article says (again, I'm not a Node or Go expert) it seems like this problem was directly alleviated by Go and the speedup wasn't because Go is closer to the metal, but ultimately had a different method of handling many async network calls.
- chadscira 10y agoYep thats what it looks like. So the take away is Go is better at handling massive amounts of open outgoing network calls. In Node.js you want to restrict this to prevent the server from choking. If they did that I bet performance would be very similar.
- wwwigham 10y agoI don't think it was alleviated directly by Go, I think it was alleviated directly by improved parallelism... By the descriptions given, their go implementation uses a worker pool to help split active work across threads, while their Node implementation did not (though in Node you'd shard across processes rather than threads) - or at least it doesn't seem like it did (despite admitting to spending a bunch of time doing processing in JS between s3 requests). Another nit: The article also implies that the height of the flame graph would indicate a performance issue, which I argue is inaccurate: Since the height of a flame graph measures stack depth, I argue it also represents abstraction. So long as most of those stacks are are equal-width, then the abstraction is low overhead (and probably has value to justify it). Generally with a flame graph you want to be making comparisons within the graph, comparing the time spent in each call (so the relative widths); not commenting on its shape in-general (though it does always make for a pretty blog post).
- aikah 10y ago> I don't think it was alleviated directly by Go, Yes it is, Go is truly concurrent, NodeJS is not. Go has green threads in userland, NodeJS does not. A Go program can actually perform multiple operations at the same time since Go coroutines are implemented at the language level, NodeJS cannot. Obviously Javascript is more expressive but Go programs are easier to read and maintain. With Javascript anything goes.
- WayneBro 10y agoGo has multithreaded concurrency. Node JS has multiprocess concurrency.
- aikah 10y ago> Go has multithreaded concurrency. Node JS has multiprocess concurrency. Go also has "multi-process" concurrency. Go is both concurrent and parallel, Go coroutines will spawn on every processor available by default. NodeJS needs an external tool like Redis to enable "multi-process" communication. Go does not.
- wwwigham 10y agoNonsense. You don't need redis for multiprocess communication in Node - child processes spawned have a communication channel with the parent whereby they can efficiently send messages (in the form of json objects) back and forth. (Or you could open your own shared file descriptor, like how you could do multiprocess message passing in any lower-level language.) There is little difference in usability between message-passing goroutines and message-passing child processes in node - just less syntactic sugar. Go makes it more frictionless to write parallel code than in Node, but its certainly not impossible to write good parallel code in Node. I wouldn't blame you nor the article author for not understanding the distinction - most people hear "Node is single threaded" and just accept that at face value. Coming from Ruby or Python, where the fork-process-to-be-parallel scheme is common, I am familiar with this variety of parallelism.
- jondubois 10y agoI guess you're probably not familiar with the whole "Why I switched from Node.js to Go" rhetoric - This article is just one of many. I've heard this "The Node.js event loop gets saturated" argument so many times - It's the #1 argument used in all articles which promote switching from Node.js to Go. The real reason why the event loop is saturated is because your Node.js process is doing too much work! The solution is to split your process into two (use the Cluster module or a load balancer - It's super easy). With goroutines and the like, all Go actually does is delay the inevitable point when you have to split your main process into two... It doesn't solve the problem, it just delays it... I don't know how Go handles the situation where a process gets too many requests... Maybe it just drops requests (instead of adding latency like Node.js)? I don't know... But once a program maxes out on total available CPU, bad things will happen! It doesn't matter what language/engine is being used; whether requests will start lagging + timing out or that they will start to get rejected outright; programs cannot transcend CPU constraints. I don't mind people switching to Go from Node.js because "they feel like it", but I don't think it's fair to write an article about it claiming that Node.js is unfit for technical reasons. There is no meat behind this argument at all and I'm just tired of seeing it resurface again and again and again on HN. It's starting to look like a propaganda campaign.
- rounce 10y ago> With goroutines and the like, all Go actually does is delay the inevitable point when you have to split your main process into two... It doesn't solve the problem, it just delays it... Yes, but Go's concurrency model is far easier to reason about. "I _want_ to do this thing", and the runtime handles the _how_ and the doing. No need to draw up some IPC messaging protocol to handle trivial tasks safely. It's a language feature (ugh sounds so jingoistic). The cluster module is nothing like goroutines in concept or in practice. You're making some mighty big assertions there, all the while disregarding the obvious weakness of a _single_threaded_ event-loop. I'm a total Node.JS fanboy since 0.2, but as was mentioned elsewhere in the comments, every language is making trade-offs: substituting shiny new concerns for it's own achilles heel.
- sotojuan 10y agoYou're giving Node devs too much credit. Most Node devs know nothing beyond `fs` and `express`. For some strange reason they refuse to learn about the standard library beyond the very basics.