6 ms·
Well written, good description and nice demo. Would love to see more on how this is different to (or better than) Akka. The programming model is actually clos
by jaimefjorge 13y ago
Well written, good description and nice demo.
Would love to see more on how this is different to (or better than) Akka.
The programming model is actually close to Akka (with actor systems, supervision, receive method, message passing, etc).
The article states that Akka has no true lightweight threads. The guys behind Akka have put it running with 50M messages/second[1] and perfomance vs erlang seems to be good as well [2][3].
Perhaps a benchmark would be great.
Thanks for sharing.
[1] http://letitcrash.com/post/20397701710/50-million-messages-per-second-on-a-single-machine http://letitcrash.com/post/20397701710/50-million-messages-p...
[2] http://uberblo.gs/2011/12/scala-akka-and-erlang-actor-benchmarks http://uberblo.gs/2011/12/scala-akka-and-erlang-actor-benchm...
[3] http://musings-of-an-erlang-priest.blogspot.pt/2012/07/i-only-trust-benchmarks-i-have-rigged.html http://musings-of-an-erlang-priest.blogspot.pt/2012/07/i-onl... (discussing millions of messages is a good signal IMHO).
- pron 13y agoThe main capability provided by Quasar is the fiber, or the lightweight thread. It is the same as a normal Java thread in the sense that it can block – on IO, on a DB call, or on a synchronization mechanism. This makes the programming experience very natural. The actor and the channel abstractions build upon fibers. Akka doesn't have lightweight threads at all. You implement a message-handling method, but it must not block on, say, a DB call, lest it block the entire thread it runs in. An Akka actor simply must not issue a DB call: it's as simple as that. With Quasar things are different: you pull messages rather than implement a callback; you can block: on IO, DB, lock or anything else. The programming then is not only simpler, but also more powerful. For example, Quasar supports selective receive - just like Erlang.
- saryant 13y ago> Akka doesn't have lightweight threads at all. You implement a message-handling method, but it must not block on, say, a DB call, lest it block the entire thread it runs in. An Akka actor simply must not issue a DB call: it's as simple as that. That's not quite true. Yes, you block that thread but this is why you configure actors with blocking calls to use their own dispatcher. For DB queries you typically put querying actors onto a thread-pool dispatcher where pool size ~= available DB connections. Selective receive is also quite easy to implement in Akka using stash().
- arielweisberg 13y agoI am really looking forward to where actor frameworks like Akka are going, but that seems like a leaky abstraction to me. I shouldn't have to define extra actors or figure out thread pool concurrency levels to do blocking operations like lock acquisition, waiting on conditions, IO etc. A framework that that doesn't allow that adds zero value to me because I am not willing to ask others to reason about that sort of thing. Not having that kind of transparency makes it difficult and dangerous to convert existing code bases that use traditional concurrency primitives. I would like to have thousands or millions of actors, but for now I am stuck going to 1:1 with threads.
- pron 13y agoI agree. That's why Quasar starts by providing true lightweight threads - you can block, wait on conditions - whatever. Only, you can have millions of those. On top of these fibers, Quasar gives you Go-like channels and/or Erlang-like actors (I say Erlang like because they follow the Erlang model closely: you pull messages rather than implement message callbacks, they have selective receive etc.)
- rdtsc 13y agoQuasar looks very cool. How does pre-emption work? I know Erlang's VM count an actors' "reductions" -- bytecode instruction and after a certain number preempts that actor and lets other run. How does that work in Quasar? Does an actor have to explicitly yield, sleep, do IO or run receive?
- jamesaguilar 13y ago> An Akka actor simply must not issue a DB call: it's as simple as that. Must not issue a synchronous db call, if I'm reading you correctly. I assume most DBs also provide async interfaces, or you could create one yourself.
- jeremyjh 13y agoThat is not a correct assumption. Most DB vendors only provide JDBC drivers. There are some async drivers, but there is no standard for them and availability and quality varies substantially. This problem is repeated for other network libraries - if they weren't written specific for NIO then you have to KNOW that and you have to be sure you run that Actor in it's own thread. Its a leaky abstraction.
- mark242 13y agoAn Akka actor simply must not issue a DB call That's untrue. With Akka's pipe pattern, you can take the results of any future and pipe it back to the sender, including using a map on the future if you like. This is how we do reactive database calls in Akka. For example: def receive = { case msg => { val f = future { myDatabaseResult(msg) } f map { result => myTransformResult(result) } pipeTo sender } } At no point does this actor block. Assuming you even have something like Play calling this actor, you wouldn't be blocking there, either, you'd take the result from the actor, likely map it to a result, and Play would asynchronously return that. My basic rule is that if you're typing Await.result anywhere in your Play/Akka code, you're doing it wrong.
- pron 13y agoThere are many ways to do asynchronous programming employing functional approaches. The difference is that with Quasar you can use them if you like but you don't have to. You can issue a plain-old JDBC call, and at no point will the thread block, either, but the actor will: because it's simple, familiar and intuitive. You don't need to learn so many unfamiliar patterns. You program as you normally would a single thread.
- dxbydt 13y agoOk, so issuing a blocking call is "simple, familiar and intuitive". Invoking a Future or a Promise is "so many unfamiliar patterns". Yes Sir, with this attitude I hope to make a remarkable progress in my tech career :) Seriously, there is nothing mysterious or magical about shoving a "plain-old JDBC call" into a Future. http://en.wikipedia.org/wiki/Future_(programming) http://en.wikipedia.org/wiki/Future_(programming) Remarkable demo, btw. But lets not run down other approaches simply because one might, god forbid, have to "learn so many unfamiliar patterns".
- andrewvc 13y agoI think you're pretending that removing the ceremony of the Future isn't a significant difference. Your point is correct, but you're missing the forrest for the trees
- eeperson 13y agoHow does the Quasar know when it should defer execution of something that might block? Does the user declare this in some fashion? In the article, it looks like this is done with try-with-resource blocks.
- pron 13y agoThe try-with-resource block is used to delineate an atomic transaction, and is part of the SpaceBase API. An example in the code for a blocking call is the call to receive. Quasar identifies blocking methods if they declare that the throw a SuspendExecution exception, marked with a @Suspendable annotation, or listed in an external file. Pulsar, Quasar's Clojure API, marks suspendable functions differently, but that's an implementation detail.