5 ms·
Bullet-proof Node.js coding
- stephenhuey 16y agoThis arrived just in time since I deployed my first Node app on Joyent last night! Great examples--they're all pretty new to me, but I'm planning to revisit your tips when I get further along.
- ddispaltro 16y agoIm curious on node fibers. They seem like a second class citizen in node, any chance they will become mainstream or will it always be like Twisted is to Python.
- tlrobinson 16y agoMost of the Node core team is vehemently opposed to anything they consider a language extension, which fibers arguably are, so I doubt you'll be seeing them baked into Node any time soon. See: https://groups.google.com/d/msg/nodejs/GDqkQzmnwHM/FKETaPivXH4J https://groups.google.com/d/msg/nodejs/GDqkQzmnwHM/FKETaPivX...
- BillSaysThis 16y agoFairly amusing that a page with this title returns a 404 at this moment (and I tried reloading twice more).
- allan_ 16y agoseems like laurenzos bulletproof node.js code just got caught in the eventloop
- pjscott 16y agoThe site is running on Wordpress. Incidentally, one of the major reasons for Wordpress blogs to go down under heavy traffic is excessive keep-alive times causing too many Apache threads to be open. It's exactly this lots-of-connections problem that node specializes in handling gracefully.
- pjscott 16y agoA postscript to this, now that the blog is back up and I can do some measurements: the server is Apache 2.2.14, and it's using the default keep-alive timeout value of 15 seconds. Looks like a typical case of Wordpress and Apache with the default configuration suddenly getting slashdotted. More on this from patio11: http://www.kalzumeus.com/2010/06/19/running-apache-on-a-memory-constrained-vps/ http://www.kalzumeus.com/2010/06/19/running-apache-on-a-memo...
- stellal 16y agoThat was embarrassing. I do know how to craft a good apache config, and am just going to claim a case of being stupid. It is ironic that node is in fact designed to handle this type of memory/connection scalability problem reliably, but in this case it was pure administrative (me) error.
- _pdeschen 16y agoThrow nginx in front :-) http://blog.rassemblr.com/2011/01/wordpress-need-for-speed-optimization-with-nginx-caching/ http://blog.rassemblr.com/2011/01/wordpress-need-for-speed-o...
- allan_ 16y agoomg excessive keep-alive times
- Cyranix 16y agoCache link: http://webcache.googleusercontent.com/search?q=cache:http://stella.laurenzo.org/2011/03/bulletproof-node-js-coding/ http://webcache.googleusercontent.com/search?q=cache:http://...
- cpr 16y agoExcellent, meaty article with a lot of practical examples and hard-won knowledge.
- sausagefeet 16y agoAnyone used node-fibers? What are the gotcha's?
- grayrest 16y agoMain gotcha is listed in the "Garbage Collection" section of the readme: https://github.com/laverdet/node-fibers https://github.com/laverdet/node-fibers
- tlrobinson 16y agoWhile this is a good article, things like this make me wonder if Node's asynchronous programming model is a good one. Certainly I don't think it's worth the mental overhead when you aren't dealing with highly concurrent IO situtations. I constantly feel like I have to jump through hoops when programming against async APIs. None of the code in the article feels "elegant" to me. Of course the popular alternative, preemptive multithreading with shared mutable state, is probably worse.
- ashish01 16y agoCoz you mentioned elegant sync programming. I think the async CTP for C# solves this problem of nested callbacks. Take a look here http://channel9.msdn.com/Blogs/Charles/Anders-Hejlsberg-Introducing-Async http://channel9.msdn.com/Blogs/Charles/Anders-Hejlsberg-Intr...
- jschrf 16y agoYou can try this stuff interactively here: http://www.wischik.com/lu/AsyncSilverlight/AsyncSamples.html http://www.wischik.com/lu/AsyncSilverlight/AsyncSamples.html (requires Silverlight)
- tlrobinson 16y agoThis is a great overview of async vs. sync IO.
- sausagefeet 16y agoI am in the same boat as you, here is a reddit discussion from a similar NodeJS post: http://www.reddit.com/r/programming/comments/g9zbg/building_a_nontrivial_app_in_nodejs/ http://www.reddit.com/r/programming/comments/g9zbg/building_...
- jerf 16y agoI've criticized Node.js in the past on this site but I actually only recently realized what is really wrong with it in a strongly-grounded computer science way rather than an intuitive way. Or rather, wrong with the asynchronous event-based programming style in general that Node.js adopted, rather than Node.js in particular (which is a fine implementation of the bad idea). Does anyone remember the structured programming arguments that occurred, oh, ten years before I was born? There was a lot of arguing back and forth, but one of the arguments made was that when your program was structured, your position in the program means something. Just making up some quick psuedocode: def x(y: int, z: int): for i in 1 to 10: --> print i * y + z def a(b: int): for i in 1 to 5: print i x(b, 3) At the line that I marked, the very fact the program counter is pointing there, and by extension the stack trace up to the point given, means certain things. We know we have an x and a y which aren't just "undef", we know we're in a call from a (in this case), and therefore, any preconditions or invariants that are provided by those functions are also in effect at this point in time. One of several reasons spaghetti code is bad is that the program counter means much less; we don't know how we got there, we don't know what invariants are in effect, in the old school assembler case we know almost nothing at all, for all we know we just lept here with a goto. As is almost always the case, this is a small trivial example, but when you start layering many things on top of each other, layering in functions that provide safe file handling or other resource management or state machines or any of the other tools we've built on structured programming or its smarter child Object Orientation, it becomes difficult to in some cases impossible to follow all this in your head. Or deal with the work to make this stuff compose together properly without layers actively stomping on each other. After spending some time with the modern functional world and their increasing focus on composability, working with async event programming feels like stepping back in time 20 years. Asynchronous event-based code is not as bad as old-school assembler, because the event handlers themselves are still using the ideas of structured programming internally. But the code as a whole is spaghetti code. I'm not the first to say that, but it turns out upon reflection it's not a slur or a metaphor, it is actually descriptive and fair. Async event code actually does share many of the critical properties of spaghetti code, as the term was first used. You don't have a call stack, you don't have the invariants, you're just adrift in the code. Of course with massive amounts of discipline you can function anyhow. You can program structured code in assembler with massive amounts of discipline. But A: you are spending valuable developer mindpower maintaining that discipline which is better done by a language/runtime/VM, no matter how smart you are you're still better off spending your smart on something other than raw plumbing and B: it's actually harder than you think. We've so thoroughly, utterly internalized structured programming since even before I was born that we can't hardly even see what we're getting out of it, and consequently we don't easily realize what we're giving up when we adopt this style. We aren't any better people than our assembler ancestors, we're not particularly more disciplined than them, and they switched to structured programming for a reason. I'm this critical because I'm actually trapped in this style at work, fortunately just in one of several subprograms but it's still annoying as hell and the one that always takes far longer to work with than I'd like. It's an excess of experience, not a deficit, causing me to be this critical. And I've really come to loath this style. Compiling is for computers, not humans. That's what Erlang and similar languages that can take care of the asynchronousness at the VM/language level bring to you; they bring you at least back up to structured programming in power and safety, and possibly beyond. And the arguments about how wonderful async event based programming is and how you've got it all under control and how it's performant and not a problem sounds to me like an absolute repeat of assembler programmers ranting against structured programming back in the day, to an almost scary degree... and every bit as correct and likely to win the future.
- jhrobert 16y agoI'm experiencing "node anxiety", let me explain: There really are two kinds of functions in a node program. Synchronous functions and asynchronous functions. This has major consequences during refactoring when what used to be a synchronous function now needs to become an asynchronous function => all synchronous functions that used to call the synchronous function needs to be turned into asynchronous functions themselves. Sometimes the ramifications go way beyond first expected. Sometimes the ramifications turned to be massive. This becomes worse when one realizes that synchronous function are much more readable, half the code and about 5 times faster than asynchronous ones (see http://jsperf.com/asynch-cost http://jsperf.com/asynch-cost) Eventually the idea of refactoring a synchronous function into an asynchronous function becomes a source of worries. And that, my friends, is not something easy to figure out and is what I call "node anxiety"
- noacctplz 16y agoFor #1, why not suppy a success and failure callback function to your doSomeAsyncCall function? There is no reason to muddle those two lines of logic together (which is the real reason for the described error). And for #2, Relying on javascript hoisting functions isnt a smart way to keep your code organized.