5 ms·
At first, I was ready to dismiss this article completely. However, this paragraph: "While Java or Node or something else may win a benchmark, no server has the
by ebiester 13y ago
At first, I was ready to dismiss this article completely. However, this paragraph:
"While Java or Node or something else may win a benchmark, no server has the non-blocking ecosystem of Node.js today. Over 50k modules all written in the async style, ready to use. Countless code examples strewn about the web. Lessons and tutorials all using the async style. Debuggers, monitors, loggers, cluster managers, test frameworks and more all expecting your code to be non-blocking async."
is true.
Java has had all of the same async capabilities for many, many years, but nobody uses them because the blocking paradigm is simply easier.
That said, if true scalability is required, I'd suggest living with Akka and the cleaner actors paradigm. However, it's true that eventually you're going to run into the barrier that the vast majority of the java ecosystem is built on blocking io.
(That said, with Java 8, I think we have a real opportunity to change that. I think a parallel "lean java" ecosystem is coming.)
- dj-wonk 13y agoRe: "Java has had all of the same async capabilities for many, many years, but nobody uses them" That's exaggeration. Lots of Java libraries use async and concurrency. Java 7 has NIO.2 which is easy to use. There is also Netty; many projects build upon that. I'm not here to say Java's ecosystem is richer or better; I'm just saying exaggeration is not useful. Re: "the vast majority of the java ecosystem" I don't mean to sound dismissive, but lots of languages have code you probably don't want to use based on your preferences or needs. So? Don't use the vast majority of libraries. :) You probably don't anyway. UPDATE: See also Akka and Clojure's concurrency for useful, popular approaches for the JVM.
- nostromo 13y agoPlayFramework (which I can't recommend enough) makes async and continuations super easy in Java. http://www.playframework.com/documentation/1.2.7/asynchronous http://www.playframework.com/documentation/1.2.7/asynchronou... Play also dramatically improves Java's general... cruftiness.
- saryant 13y agoYour link points to the (very old) 1.x branch docs. http://www.playframework.com/documentation/2.2.x/JavaAsync http://www.playframework.com/documentation/2.2.x/JavaAsync
- chaostheory 13y agoyeah I was about to say the same since 1.x and 2.x are drastically different
- agibsonccc 13y agoI use akka for much if not all of my heavy lifting on the JVM. Admittedly, it's a little awkward sometimes, but if you make the right tasks non blocking (run it in a future), you would be surprised at the performance increase you can net.
- drdaeman 13y ago> Over 50k modules all written in async style, ready to use Actually, not true in "all" and "ready to use" parts. I suspect there are enough libraries that, even while exposing supposedly-async API block under the hood. Or require careful handling. Even core Node libraries are not throughly async. One obvious example is `crypto`, where only I/O stuff (accessing OS entropy pool) is async. Good luck generating a keypair in event loop.
- matt_heimer 13y agohttp://mailinator.blogspot.com/2008/02/kill-myth-please-nio-is-not-faster-than.html http://mailinator.blogspot.com/2008/02/kill-myth-please-nio-...
- rdtsc 13y ago> no server has the non-blocking ecosystem of Node.js today. Over 50k modules all written in the async style, ready to use. I read it as -- "Node.js doesn't properly support isolated units of concurrency and thus due to being forced to write callbacks inside callbacks that call errbacks for everything, we now have over 50k modules full of callback chains and we call this a GoodThing(tm)".
- etanazir 13y agoI'll call you when you need me.
- chc 13y agoI don't think that's entirely fair. The standard callback model can easily be converted to a promise-based one with Q or a CSP channel-based one with ClojureScript's core.async or any number of other models.
- rdtsc 13y agoIt is but most of those module are not written like that. For example Python's eventlet and gevent are based on greenlet. Greenlet is based underneath on large select/epoll/kqueue/poll loop. So there are callbacks for IO readiness there. However they manage to do some tricks to hide that away behind green threads at the user level. So a user can say: " authorize() ; check_database(); charge_credit_card(); update_database(); send_response()" logic properly for each request for example. Without having to split that logic into a chain of callbacks just because some of them might involve at some point making a socket call.
- ebiester 13y agoWhile I'd tend to agree, this may be a case of "worse is better." In the java ecosystem, most of it assumes blocking IO. If you're trying to get out of this mindset, the ecosystem can get in your way -- or at the very least, it's not making your life easier. For many things, this is fine. If I'm not twitter, I'm trading increased scalability for readability almost every time. For projects that just need occasional async, I would prefer the grails 2.3 model -- http://grails.org/doc/2.3.0.M1/guide/async.html http://grails.org/doc/2.3.0.M1/guide/async.html -- which will get you 95% of the way there in a more readable way. ___ However, I am a bit more charitable toward node. I think this may be a case where there is enough momentum that, as people start hitting the harder problems, engineering solutions will sprout up, and the platform will mature with better patterns turning up (including generators and promises.)
- rtpg 13y agoThis is slightly off topic, but if we're talking about language capabilities for async: Something I only figured out fairly recently but that shocked me is that Haskell, with its lazy evaluation, you can essentially get asynchronous programs for free, and still write in a synchronous style. While by default the IO monad is strict (basically makes IO stuff synchronous), there are some non-strict actions that are really easy to use. Imagine the following program: Open two ports, and print the first couple of bytes recieved from each port. In node (at least from the callback-based stuff), at one point you're going to have an inevitable : while(!done){} //waiting in Haskell, this program looks roughly like: main = do socket <- someSocketInitCommand socket' <- someSocketInitCommand response <- hGetNonBlocking 1024 socket response' <- hGetNonBlocking 1024 socket' print ("1st socket : "++ response ++ "\n second socket:"++response') Lazy IO in Haskell is what I call blocking on data-dependencies: because of how lazy evaluation works, Haskell is able to keep on going until the very moment you need the result from some async call. It's even crazier that Haskell has the holy grail of async programming : the function that transforms a synchronous function to an asynchronous one. Instead of having main = do x <- a you simply do main = do x <- unsafeInterleaveIO a a becomes asynchronous , and nothing else in your code has to change. (from what I understand unsafeInterleaveIO is called like that because it makes the order of your IO actions a bit uncertain, which is a problem for print statements, but when you're doing async programming this is already the case!) Laziness makes Haskell crazy neat, and I would really love for lazy features to enter other languages. There are some issues (error handling mainly) but it gives you the best of both worlds, I find. ( I am by no means a Haskell expert, so all this might be wrong, but in my experience things work this way-ish)
- implicit 13y agoThat's not all. This code: foo = do result <- do_first_thing do_second_thing result Kinda sorta roughly desugars into something like this: function foo(cb) { do_first_thing(function(result) { do_second_thing(result, cb); }); } Synchronous and asynchronous Haskell APIs can have the exact same interface.
- saryant 13y agoLook at Akka, it brings a very rich concurrency toolkit to the JVM, building on the already-excellent primitives provided by the standard library. Futures and actors are quite elegant and simplify reasoning about concurrency.