9 ms·
We switched to Node.js: the good and the not so good
- DoubleCluster 14y ago> It terms of performance, we also have seen a significant (about 25%) bump in terms of feeds processed by second per server. They rewrote the entire codebase and obtained for just a 25% gain? It doesn't sound like they are very happy to be coding in javascript now either. Everyone: please don't rewrite your code, it's almost never worth it. The one exception is rewriting a core part of an algorithm in C for speed (the last 10x speedup).
- omarkj_ 14y agoThere are other reasons for rewriting like getting to a more easily maintainable code or when a previous solution has simply outlived it's usefulness. Also, C is not the only language worth rewriting in.
- voidlogic 14y ago"Also, C is not the only language worth rewriting in" Agreed! I would really like to see someone write a node.js and Go back-end for the same front-end and do a head to head comparison. As someone who spent a fair amount of time rewriting node.js prototypes in Go, I'm probably biased. I feel like javascript is a much less maintainable language. Perhaps is was the original node.js implementations (I don't think it was), but the Go versions were always faster, used less memory and IMHO were more readable.
- iends 14y agoAny particular lessons learned rewriting from node to Go? I've got a small but growing node/socket.io app I figured I'd have to one day rewrite in go if I really wanted it to scale.
- voidlogic 14y agoNothing too unexpected, off the top of my head, I've noticed: * Use Go tip; You can grab a snapshot review all the open issues for that snapshot (most are enhancements). * Like any re-factor doing it sooner as opposed to later is less work :) * Do some "from scratch" Go projects before doing re-factor projects to get your legs under you (if they are not already there) * Write Go in Go, not C/Python/Java in Go. This is harder than you think when you get started, but, if you ask for help and people tell you you are fighting the system, carefully consider their advice. * A lot of the Go community likes to use single letter variable names in contexts like receivers, struct state (just look at the stdlib), buck the system, don't do that, use short camel case names. The next guy / you in six months will be glad you did. * If you have a Java/C++ background you might often write a single threaded version of a daemon and later multithread it later, this is generally an unnecessary step in Go. * The Go versions really are not much larger (LOC) * There is lots of useful Go code on github (don't be afraid to try them) * If you are doing front-endy kind of stuff supplement "net/http" with Gorilla where needed whenever you can rather than rolling your own. ttp://www.gorillatoolkit.org/ * "go tool prof" is a great tool, know how to use it and its top20 / web commands. Even if you don't feel the pain, use it and you will learn what things you do are expensive and it will keep trouble from sneaking up on you. * If you are using a SQL based store, use a driver that implements the interfaces in "database/sql" rather than providing its own interface. This will make your life very simple if you need to migrate between mySQL <-> Postgre, etc * LiteIDE is a nice lean cross platform Go IDE that includes syntax highlighing, autocomplete (with gocode) and debugging support. The only think I had to do was write my own syntax highlighting theme, based on Solarized, because I thought the included ones were gross.
- julien 14y agoWell, the reason we rewrote was not to explode all benchmarks. The reason we rewrote was to be able to ease the maintenance of our code =)
- DoubleCluster 14y agoThat's fine. Did the code become easier to maintain? It's not clear from the article. The "The good" section is relatively weak and the "The not-so-good" has some painful points about memory management and api instability. It sounds a bit like you guys rewrote it because node.js is hot and you then stuck with the rewrite because of sunk costs. Or am I imagining things? Thanks for sharing your experiences with us. I'm just asking those questions because I want to learn more about them.
- julien 14y agoWell, we assumed everyone knew about the good... so yes, we're happy with the rewrite and will probably never go back. Also, a 25% saving in servers for us translate in several thousands of dollars saved monthly. Not negligible :)
- octo_t 14y agoHow much development time did this cost though, when you could have been adding new features and improving the user experience?
- julien 14y agoHard to assess exactly, but we were not adding feature and improving the user experience mostly because maintaining the previous code base and evolving it was so costly.
- rartichoke 14y agoYeah but in your article you said you're not even sure if this is because of node. You made some architectural changes in your code base and hinted that might have been a reason for the speed boost too. The article might as well be written as "we refactored our code and got a nice speed boost".
- jonpacker 14y agoThey did not say anywhere that the 25% speed gain was the reason they did it...
- blacktulip 14y agoI kind of agree that 25% gain doen't justify codebase rewrite, let along language/framework switching. Perhaps they are doing this with future traffic peak in mind. Premature optimisation, I know. Probably they've already cleared up other important items on their todo list. What interested me most is the community part. I've always thought ruby/rails community is awesome. Maybe I should start learning some JavaScript now.
- dnu 14y agoIt depends on how large the code base is. Rewriting a 10k LOC project isn't a big deal, compared to a 10 mln one. And a rewrite doesn't have to target performance only, but ease of maintenance too.
- PommeDeTerre 14y agoIf ease of long-term maintenance is a goal, then JavaScript is the wrong approach.
- nkohari 14y agoWell that's just, like, your opinion man.
- gbog 14y agoYou have better ways to ask for explanations. Not the OP but I can give some reasons for Javascript and Node.js to not be the best option for a rewrite if the goal is longterm maintainability: - js / node.js is very young, it might fade out of fashion, and in 10 years it is not impossible that good coders in js will be hard to find. - Readability and simplicity are prominent in this context, and js has a syntax that is less than optimal in this regard. - Maintenance tooling may be lacking. If I were to choose a language for a project that I new will be big and will need care in 10 or 20 years, I'd hesitate, and maybe choose Java (which I hate) or Python (which I hate less). If in a risk-things mood, I'd give Go a try.
- OriginalSyn 14y agoI don't see how finding JavaScript programmers is going to be a problem in 10 years... even if they started now it would take, at least, that long to fully deprecate the language out of the browser. NodeJS may go away but I think betting on JavaScript going away are some pretty long odds.
- niggler 14y agoNode.js may be young but 98% of the code can be reused (and if you are careful, you probably wrote the fallbacks already). V8 can be built separately. When you understand the zen of javascript and try to write in a consistent manner, JS is more readable than C. I equate these concerns with arguments about how lisp or scheme is unreadable. The ecosystem for tooling is expanding, albeit slowly. However, most of your code probably could be implemented in a way that can be run in browser (e.g. XLS parser: http://niggler.github.com/js-xls/ http://niggler.github.com/js-xls/) which is where I see the real value in node. Aligning the languages means fewer moving parts and potential points of failure (as opposed to having to worry about quirks in implementations of many languages and worrying about features supported in one context but not the other)
- viraptor 14y agoI'd look at it from another side. They took a working project which they knew well and transferred it completely to a different platform. The first "complete" version of the rewrite had 25% more throughput. In that case it's a pretty good achievement, since the rewrite will have a lot more low-hanging fruit regarding performance improvements, than a polished, existing product. I'm used to see rewrites which are at least a little bit worse than previous versions due to all the work done to squeeze everything out of version N-1.
- nivertech 14y agoI think the reason they only got 25% gain is because they already used Async IO with Ruby eventmachine. Another reason might be, that their workload is IO-bounded, so faster VM like V8 doesn't help.
- jahewson 14y agoIf the initial version was IO-bound wouldn't they get a 0% gain from re-writing?
- Peaker 14y agoMy experience is the exact opposite. Trying to make do with horrible code for long periods of time, suffering through bugs in every change... Until we finally rewrite it. I've never regretted a rewrite, and it has always ended up significantly better than the original (possibly because the horror threshold for rewriting is high, so that's not saying much).
- DoubleCluster 14y agoIn my experience it's quite doable (with a good IDE) to refactor the working but messy code into something maintainable. It might take the same amount of time as a rewrite but you'll still have all the features and corner cases covered. Usually refactoring will be much faster though.
- Peaker 14y agoI disagree. Incremental changes are not always capable of reaching point B from point A. A large, extremely messy code-base can make even trivial changes unsafe, let alone large changes. The effort required not only to figure out what point B is, but also how to safely reach it from point A is immense. Much much harder than a rewrite. However, it is a very good idea to meticulously read the bad old code and write down a list of things it handles -- to make sure none of it is missed in the rewrite.
- nicholassmith 14y agoI tried Node, because it was the new hotness and trying new things is great. It was distinctly Not For Me, for many of the same reasons that they've found; many tutorials are out of date in subtle ways (I like to think of this as the Rails effect from way back in the good old fun days), the language is just painful to structure and read over for my syntax processing. There's definitely a lot to like, and like they said it's still a very new world with a lot of exploration to be done.
- blacktulip 14y agoI have not tried Node (or in fact JS as a whole) yet. But it seems very hard to avoid JS in these days. I am going to learn it in a few months. Can anyone give me a rough idea how bad it is? (I know some Obj-C so is JS worse than that?)
- superbobry 14y ago[1] can give you some insight on the dark side of JS. Also, avoiding JS in some way or another is not that hard, esp. since there're a lot of languages which compile to JS, most notably CoffeeScript and ClojureScript. * [1] http://wtfjs.com * [2] https://github.com/jashkenas/coffee-script/wiki/List-of-languages-that-compile-to-JS
- dagw 14y agoAs much as I love CoffeeScript, it's not a substitution for learning JavaScript. CoffeeScript is basically just JavaScript with a prettier syntax and if you don't understand JavaScript you won't understand CoffeeScript.
- pooriaazimi 14y agoVery true. I love CoffeeScript very, very much. It's my favorite language - I like it even better than ruby, if you believe me! I like using indentation instead of stupid 'end's that only God knows are ending a loop or a def or something else, I like the use of ... instead of * (for splats), and a few other things. But, as much as I like CS and hate (really hate) JS, I have to agree with you wholeheartedly. You must know JavaScript well. Variable/function hoisting won't bite you in CS, but other JS idiocies will. Read Douglas Crockford's "JavaScript: The Good Parts" at least twice (and take a lot of notes). It's the best no-bullshit book on JavaScript (the language, not "how to use JavaScript in Node/front-end web design") around.
- deleted 14y ago[deleted]
- davidw 14y ago> What we liked the most of Javascript was the fact that it’s an asynchronous language ‘by default’. That's not strictly true - a "while (true)" will lock up a Node process as far as I can tell. I think a more accurate way of stating it would be that "Javascript API's and libraries tend to be written with asynchronous use in mind", with lots of callbacks. If you want something that's async at a deeper level, Erlang is worth a look.
- StavrosK 14y agoWill a "while True" not lock up an Erlang thread?
- davidw 14y agoNo: Erlang has an internal scheduler that makes sure that no process can lock the whole thing up. It's not impossible to wedge Erlang, of course, it's just not quite so easy.
- StavrosK 14y agoAh, so it uses preemptive rather than cooperative multitasking. I find that locking the whole thread is usually an error, so preemptive multitasking wouldn't help much there, and I like how cooperative multitasking lets me reason about the program, but I can see the benefits in both approaches.
- jerf 14y agoErlang does not have a problem reasoning about the program, because it doesn't share any data. They are actually independent from each other in the same ways that two OS processes are independent from each other (that is, there are still resource contention issues but abstract correctness don't unduly depend on each other). I'm running out of polite ways to say this, but Node advocates really need to learn about other ways of doing things before advocating so confidently that Node's way is better. Cooperative multithreading does not have the reasoning advantage, which is one of the reasons why it has been abandoned for so long at the OS level. It's incredibly harder to work with that preemptive multithreading sorts of things, combined with other techniques that have been developed over the decades. (Also, I said "Node advocates" and not StavrosK or "you" specifically; I mean that more generally than just your post here.)
- niggler 14y agoThe complaints were summarized well by Crockford http://www.crockford.com/javascript/javascript.html http://www.crockford.com/javascript/javascript.html Most of the people writing in JavaScript are not programmers. They lack the training and discipline to write good programs. JavaScript has so much expressive power that they are able to do useful things in it, anyway. This has given JavaScript a reputation of being strictly for the amateurs, that it is not suitable for professional programming. This is simply not the case.
- antihero 14y agoSay I'm a Python developer and I'm looking to write services that are fast. Would I likely be better off going down the route of node.js, Go, Haskell, Erlang? I mean they are all fantastic languages and I've dabbled in most of them but from what I've read, Go seems to be the best one to use if you don't want to shake your world up, but if you do, Haskell or Erlang are nice new paradigms to dive into. Is this true?
- pilgrim689 14y agoErlang has decades of use in fast, robust, large telecommunication systems. Haskell promises more robustness than any other platform as well as performance sometimes comparable to C. Its downside is just that steep learning curve though. So if you want speed, I'd go for those two out of your list. Go and node.js are still infants in the game, so I don't think there is enough serious software out there built with these to properly judge their effective speeds.
- codygman 14y agoI agree that Erlang is probably the best example of proven to be robust due to use in large telecommunication systems. I would also agree that Go and Node.js are still infants in the game, but I'd argue that there is enough software out there to judge Go's effective speeds. - Google is using it internally, where speed is an absolute requirement - Vitess, recently open sourced (and used internally by youtube) would definitely have to be fast for the task youtube is using it for. (http://code.google.com/p/vitess/ http://code.google.com/p/vitess/) - Desktop window manager in Go that is very fast even on lower spec machines: https://github.com/BurntSushi/wingo https://github.com/BurntSushi/wingo Just my two cents. I would absolutely stay away from node.js if you are in an environment where people touching the code aren't easily accessible, since it's very easy to write javascript that only you understand. The other languages seem to punish it a bit more, while at times it feels as if javascript embraces it.
- marekmroz 14y agoHave you tried writing services in Python and running on gunicorn or gevent?
- jondot 14y agoI am using a mix of Ruby, Node and Java in production but after some hard-learned lessons chose to minimize the Node usage to things I absolutely need. My experience with the Node community: - Great people (Substack!) - Great attitude #node.js/freenode - However, many hours spent on solving bugs in existing libraries. My experience with maintaining production Node code: - It may be more maintainable than EventMachine, but it's absolutely not more maintainable than Ruby. - V8 garbage collection is a real pain when you do work that needs it (this also includes memory held by open sockets). - Was V8 built for the server? (rhetorical) In the end, I prefer threaded Ruby code to evented Node code. I try to offset the inefficiencies of "threads vs evented" or "Ruby vs Node" by using the JVM and JRuby.
- danenania 14y agoIt seems needlessly limiting to make EventMachine and Node your only candidates. Since you've already got java in the stack, what about clojure? What about go?
- jondot 14y agoI used the examples from the original article. I think the OP ported an EventMachine code to Node. When I said 'Java' I really meant JVM. Specifically I'm using Scala. Regardless, I have a different Clojure based project, with it as well, I prefer doing what clojure has to offer in terms of concurrency (pmap, etc). I have dipped a toe in Go. Loved the fact that you get a compiled binary, ecosystem still feels skinny. Ended up concluding that in a year or two it'll be worth revisiting.
- continuations 14y agoIf you're already using Scala, why do you need Node? What does Node give you that a Scala async framework like Play or Scalatra doesn't? Also what does Ruby give you that Scala doesn't? Just wondering why do you choose to use 3 stacks (Ruby, Scala, Node) when one could be enough.
- 14y ago
- CoffeeDregs 14y agoI like JS and I like NodeJS, but I'm more of an integrator-coder and prefer frameworks, so I miss things like Django, South, mature ORMs, etc. Though I did somewhat overcome this hurdle, I particularly hurt for a migration library when building a NodeJS project (we did find a decent one, but it was young, immature and not well documented, so it took 10x the time to get comfortable working with it and then it lacked lots of features). I also missed the availability of batteries-included API libraries such as Tasty-Pie and Django-Rest-Framework. Again, it's not hard to code up a few URLs for a model, but then ... HATEOS ... default REST stuff ... JSONP support ... etc. I do look forward to switching to NodeJS and I am fairly early adopter... but it's still been too early for me.