
Quasar and Akka – a Comparison - circlespainter
http://blog.paralleluniverse.co/2015/05/21/quasar-vs-akka/
======
vamega
Seems like a very one sided comparison. Most other posts from paralleluniverse
have also come off this way.

~~~
nosideeffects
Anytime I see "Not needed" instead of "No" in a feature comparison chart, I am
inclined to just stop reading.

~~~
pron
In this case, as in many others, "not needed" means that one abstraction that
is present makes other abstractions unnecessary. For example, if blocking is
free, a non-blocking API is not needed, or if actor receives are selective,
then message stashing is not needed. Saying "no" would imply that the
functionality is missing, when in fact it is present only doesn't require a
separate abstraction.

------
kodablah
Saying Quasar supports Kotlin/Clojure as though Akka does not (considering
both languages interop with Java) is unfair. There is a difference between
bytecode manipulation making alternative JVM languages impossible vs just not
having a language-idiomatic wrapper.

There a few other parts I take slight umbrage with (e.g. pretending Akka is
heavyweight, has deployment rules, incomplete integration information, etc)
but overall a nice informative comparison if a tad biased feeling.

~~~
saryant
Some of it is definitely misleading. Saying that Akka forces you into a
logging library when it can be used with log4j, logback, provides a bridge
with slf4j, etc, is just being uncharitable. As is claiming that "commercial
tools" are needed for monitoring when JMX can be used just as with Quasar.
Same with labeling Akka's clustering support as "experimental". Akka dropped
that status from the clustering module a while ago (I had it in production for
over a year).

I get that it's marketing material so it's going to be biased but I can't help
but feel that one too many liberties were taken in making Quasar look good.

~~~
kodablah
This is most evident in the conclusion: "Akka [...] is a totalizing choice",
"blocking is free", "Akka [...] the way to go if [...] you have embraced
Scala", "Akka [...] betting on a framework and sticking with it [...] high
rewrite price", on and on. In retrospect I would remove "a tad" from the last
sentence of my original post.

~~~
circlespainter
Can you expand on why you think these statements are not correct? I think they
are thoroughly explained in the post.

~~~
kodablah
* Akka is not a totalizing choice, it's just a concurrency mechanism. Many people to not bury logic in there but in traits or other places handling normal futures. That's like saying if you use threads, it's a totalizing choice regardless of where the majority of your code resides.

* "blocking is free" is contradicted right up earlier in the post with "highlights the additional cost of the real lightweight threads in Quasar"

* I will admit, between these two choices, you must choose Akka if you embrace Scala. But the inverse is not true.

* I don't believe it's a high rewrite price any more than any other library is. Do I pay a high rewrite price for using any other abstraction? I mean I just have functions that return futures, but because I composed them with Akka I can't rewrite it?

In general I think it's unfair to make assumptions or opinions here. To
compare objectively is one thing, but to say something is a choice one way,
requires you code one way, etc is invalid.

~~~
pron
> Akka is not a totalizing choice, it's just a concurrency mechanism.

... that doesn't play nice with any other Java (or Clojure) concurrency
mechanism.

> "blocking is free" is contradicted right up earlier in the post with
> "highlights the additional cost of the real lightweight threads in Quasar"

Well, very nearly free, and the cost will drop further.

> I mean I just have functions that return futures, but because I composed
> them with Akka I can't rewrite it?

Pretty much. Java code doesn't work that way, and certainly doesn't integrate
with Scala futures. Also, you commit to using non-standard APIs in much of
your application. With Quasar you'll likely write the REST endpoint in
standard JAX-RS, and run it on top of Tomcat or Jetty or JBoss. So Akka is a
library that 1/ encompasses many facets of your application, 2/ uses non-
standard APIs everywhere and 3/ uses non-idomatic APIs that are very hard to
compose with other Java libraries.

> to say something is a choice one way, requires you code one way, etc is
> invalid.

Akka does require you to write asynchronous code throughout the entire call-
stack.

~~~
bad_user
> _[Akka] doesn 't play nice with any other Java (or Clojure) concurrency
> mechanism_

I've been using Akka in combination with Scala's Futures, with Java 8's
CompletableFutures, with Rx Observables, with in-house asynchronous queues and
I can't see how Akka doesn't play nice. With the introduction of the reactive
streams protocol, piping streams of events between multiple libraries becomes
really easy as well.

> _Java code doesn 't work that way, and certainly doesn't integrate with
> Scala futures._

Akka exposes a Future interface for Java, however I don't see the problem with
working with Java's CompletableFuture or whatever is in Guava. I've done that,
it's quite OK. Also, along with Scala 2.12 (now in milestone), Futures from
Scala will be usable straight from Java 8.

> _With Quasar you 'll likely write the REST endpoint in standard JAX-RS, and
> run it on top of Tomcat or Jetty or JBoss._

You can do that with Akka as well, I've done that, I don't see the problem
there.

> _Akka does require you to write asynchronous code throughout the entire
> call-stack._

I've worked on an RTB system processing over 30000 transactions per second,
I'm working now on a system processing real-time events coming from industrial
machines. I've been using Akka where it makes sense and while I only played
with Quasar, I do have a lot of experience with Gevent and Eventlet in Python
and the bit about "synchronous" and "blocking" code being easier (while
cheating by patching connections) is bullshit, for one because sometimes it
doesn't work creating more problems than it solves and because it doesn't
simplify anything of importance. People should write asynchronous code
throughout the entire call-stack, it's doable and fun with the right tools ;-)

I expanded a little for the why in another comment:
[https://news.ycombinator.com/item?id=9585424](https://news.ycombinator.com/item?id=9585424)

~~~
pron
> You can do that with Akka as well, I've done that, I don't see the problem
> there.

The problem is that your (JAX-RS) endpoint will then not scale as much as your
business logic.

> People should write asynchronous code throughout the entire call-stack

Ah, but why? Forget for a second about Quasar and its current implementation.
Why on god's green earth should people ever consider writing asynchronous
code? Correct me if I'm wrong, but the _only_ answer to that is "to avoid
blocking threads, which is expensive". If you had a way to make blocking
threads inexpensive and therefore _not_ have to write asynchronous code,
wouldn't that be better (even if you think async code is not hard)?

------
avodonosov
Quasar is going the right direction - writing synchronous code is better - the
code is simpler and cleaner. There is no inherent performance penalty in
synchronous approach, it's just the runtime systems of many popular languages
make it so - statically allocated stack, and some penalty of context switch
via system call. In addition to the languages mentioned in the article (Go,
Clojure core.async, Erlang), Gambit Scheme deserves to be mentioned, winch can
spawn millions of lightweight (green) threads. Also there was Stackless
Python.

BTW, no need to describe the implementation in terms of continuations. It's
just enough (I think) to allocate function activation records on heap instead
of statically allocated stack. (AFAIK continuations are also implemented
similarly, although what I've read about Go, their call stack management is
something more complex)

Also, I think the "actor model" is not the final solution for scalable
distributed programming, it's just some initial, and IMHO pretty clumsy step.
We will have better approaches soon.

~~~
felixgallo
I feel like Actor is a quantum leap ahead of all the previous and current
paradigms, like Promise and Future and Async. What do you think makes it
clumsy and why do you think we have something better in store?

~~~
Jweb_Guru
The problem, I suspect, is that there isn't really one formal "actor" model
that everyone agrees on. People have used it to describe formal models like
CSP and linear logic, practical systems like the Erlang VM and Go's green
threading implementation, and capability-based systems like the (provably
secure) SEL4; these are _not the same thing._ And, not to pick on you
specifically, this is exacerbated by confusingly referring to "promises,
futures, and async" as "paradigms." Promises and futures are for the most part
identical, and I don't see how you can meaningfully call them
"paradigms"\--they're just APIs. "Async" (async what?) is _maybe_ abstract
enough that I'd be willing to call it a "paradigm," but I don't see how actors
don't also fall into that category.

~~~
felixgallo
could you point to a place where anyone's said that Go, or any other CSP
system, are Actor systems? That would be interesting to see.

Promises and futures are not actually identical; and they're paradigms,
because they are concepts shared across a large number of different languages.
'Async' is the P in CSP, as in C# (called 'async'), and as in ES7
([https://github.com/lukehoban/ecmascript-
asyncawait](https://github.com/lukehoban/ecmascript-asyncawait)). Hope this
helps you.

------
Matthias247
Just wanted to comment on the "Blocking vs. Non-Blocking" nature of the
different actor implementions. The article here says

 _A reason for choosing the asynchronous, callback-based approach has been
that blocking plain OS threads entails significant overhead (as does the mere
existence of many threads), which can be avoided with a non-blocking API.
However, because Quasar – just like Erlang and Go – has true lightweight
threads, blocking carries virtually no overhead_

In my opinion the difference is much then whether an OS thread is blocked or
not. Being able to make synchronous-looking (but not-thread-blocking) calls
inside Actors still will block the Actor for other incoming messages for that
amount of time. So you have states were the Actor is unresponsive - and with
the right amount of dependencies between Actors you can deadlock.

A Actor which doesn't use any blocking calls internally will be more
responsive and less prone to deadlock. But of course - you have to model more
states explicetly. E.g. if I have an Actor routine that's like

    
    
      while true {
        var msg = await mailbox.Get();
        if (msg is XYZ) {
          var result = await doSthAsync()
          updateState(result)
        }
      }
    

and would like to transform that into a completly nonblocking implementation
then I would need to model an extra state and probably handle messages
differently in the timeframe between doSthAsync() was sent and the result is
received.

This can be a good thing (you can be more responsive and all states are
explicit) and also a bad thing (more verbose code).

Important is also that with the blocked Actor one get some kind of
backpressure strategy for free. Whereas with the nonblocked Actor one has to
handle that also explicitly.

I tried both concepts in my recent work, the blocked actor mainly with F#'s
mailbox processor and the nonblocked with my own implementation and personally
favor the second version now. I find it quite useful to think about and model
Actors as state machines and beeing able to handle all kinds of state
transitions explicitly. It also made deadlock prevention easier.

Nevertheless I'm seriously impressed about the capabilities of Quasar and
Pulsar.

~~~
circlespainter
I'll only add that Quasar offers several types of "send" and "receive"
operations: blocking indefintely, with timeout and even "try" variants that
will not block at all, as well as several mailbox types, so the developer can
regulate queues, responsivity (and backpressure) as desired.

------
eranation
How much does the fact you have non blocking green threads matters when you
have a cluster of 100 machines? Yes, internally in each machine there are less
kernel threads and less overhead, but If an actor on one machine sends a
message to an actor in another, does it matter if it's a jvm thread or a
fiber?

~~~
circlespainter
If you want regular code and not async, then yes, it matters: if you have a
lot of OS thread-based actors performing blocking network "send"s as part of
their regular control flow, each of them blocks an OS thread and you'll run
out of resources soon. If those actors are backed by lightweight threads
instead, which are very frugal, basically you are only limited by the network
stack.

~~~
eranation
My thought is that always the network is the bigger bottleneck. But I guess it
depends on the data / OS etc.

------
bad_user
The article is full of incorrect statements and biased opinions, I stopped
reading at some point, because even though I think Quasar is really
interesting, this article has been a turn off. Some things that bothered me
...

Akka follows the Erlang actor model pretty faithfully and what you do in the
actor model is that you model _state machines_. In Scala you can also work
with scala-async [1], which is basically what Quasar does, but that is not
enough because calling a function and getting back some future result is only
a really simple use-case, whereas in practice you get streams of messages and
the communication is a bidirectional ping-pong.

So you work a lot with context become/unbecome [2], which is very much like
what you'd do in Erlang for evolving state. This is because modeling a
communication protocol requires multiple stages and a constant dialog with the
other side. Even in a simple producer/consumers relationship you need back-
pressure. Pretending that the communication is somehow synchronous is not
going to fix the non-deterministic nature of this process and the logic will
end up looking mostly the same. This is because it's not the asynchronicity
that bites you ;-)

Quasar cannot make blocking I/O to not block threads, although it's clearly
stated in the article, but that's just wrong. You can indeed patch connections
to work with Quasar's fibers, working much like how you patch sockets in
Python with gevent, so you can create your own JDBC data-source that plays
nice, but that's not the same thing.

This really means that your pieces of I/O logic are still separated into
blocking and non-blocking (red versus blue) and I'd rather see which is which
by seeing `Future[T]` or `Observable[T]` in my function signatures. Therefore
I disagree that Quasar code is more readable, but at least I'm willing to
admit that YMMV.

Also, that Quasar actor given as an example has nothing to do with the actor
model. This is because in the actor model the actors are untyped. If you type
your actors, then you're not talking about the actor model anymore and you'd
be better off with another computational model. At the moment it is completely
futile to try to type state machines that work in a non-deterministic highly
concurrent environment. And if you go through the effort of typing those
actors, then you have to at least recognize that actors can communicate with
multiple other actors at the same time and thus expose multiple interfaces.
And then you can say that at the very least your typing says something more
useful than Object or String.

I could write more, but I got tired.

[1] [https://github.com/scala/async](https://github.com/scala/async)

[2]
[http://doc.akka.io/docs/akka/snapshot/scala/actors.html#beco...](http://doc.akka.io/docs/akka/snapshot/scala/actors.html#become-
unbecome)

~~~
circlespainter
In Akka an actor is basically a message handler; I personally think that being
able to use regular control flow constructs is an easier way to model state
machines than swapping around message handlers.

scala-async looks more like core.async's go to me, i.e. it macro-transforms
blocks of code that include special constructs into some continuation-passing
style. Quasar implements lightweight threads on the JVM (via bytecode
instrumentation, which is a language-independent mechanism), and this is a
different thing: no special constructs are needed, you just write regular
blocking code (only in lightweight threads, that have basically the same
interface and usage as regular Java threads) using normal method calls and
control flow constructs. Quasar will take care of blocking/resuming/scheduling
efficiently.

As for I/O, Quasar integrations allow lots of fibers to make blocking calls
_without_ as many OS threads blocking. The underlying implementation mechanism
is often to tap into an async API, suspending fibers when an async call is
started and installing an handler that will resume them when the async call
completes. Quasar includes such an integration with Java NIO for files and
sockets and more are available in Comsat (e.g. with servlet async, async HTTP
clients etc.).

I agree about typed actors not being too helpful in dynamic, complex and
highly concurrent environments, but in some situations (e.g. transient one-
receive actors) they can help keeping communication in check more statically.
Of course one can just avoid using types if not needed and Quasar behavioural
actors are actually untyped.

------
M8
If best things were winning we would all be using Mercurial and JS would be
long dead. Popularity and endorsment decide.

------
circlespainter
By the way I'm the author of the post so feel free to get in touch, I'll be
glad to answer any questions.

~~~
edko
On GitHub, Akka has 14659 commits, 82 branches, 150 releases, and 188
contributors. Quasar has 1753 commits, 14 branches, 9 releases, and 7
contributors.

All other statistics are also massively in favor of Akka (just look at the
numbers for this past week, or the number of contributors that are really
active in both projects).

Akka is serious business software, that companies can safely rely on, without
gambling their money. It is easy to use, performant, low risk, and has an
incredible team of very capable developers who have been perfecting it for
years. And "serious and safe" does not at all mean static: they constantly
keep pushing the state of the art (I didn't see anything in the article about
Akka Streams, Spark, the upcoming typed actors, any emphasis on the usefulness
of message persistence, ...).

If you want to challenge the market leader, you will need more than biased
reviews: you will need more people working on it, more activity, and real-life
success stories.

~~~
oldmanjay
I'm not affiliated with either horse in this race, but it would be good for
you to explain exactly what about those repo statistics favors Akka. Seems
like the numbers are larger, of course, but I'm aware of no relationship
between any of those numbers and project quality. Or anything else, for that
matter.

~~~
edko
I am also not affiliated with either.

When you choose the backbone of your architecture, there are other things to
consider, in addition to technical aspects. The numbers I mentioned give an
indication of some of those aspects.

If I look at Quasar in GitHub, it seems to have only two developers who are
really active: the same two people who are writing on this thread. Let’s say I
adopt Quasar and base my architecture on it. What happens when these guys land
a big project paying big money with a big client? Will they have time to fix
issues? Will they have time to develop new features? Will the big client
dictate the direction of new developments?

Look at Akka on the other side. They have people like Jonas Bonér, Viktor
Klang, Roland Kuhn, Mathias Doenitz, etc. People who are not only amazing
developers, but who are also thought leaders. These guys publish books on the
subject, speak at conferences, conduct massive online training, and have
industry recognition. And they are just the tip of the iceberg. They have a
team of less-famous but equally amazing rock star delelopers working with
them. Akka gets more solid as time progresses, not only technically but also
in terms of market perception.

On which of the two horses would you place your bet?

Quasar may have its technical merits, but unless it comes up with a really
compelling feature that gives it a sustainable advantage against Akka, it has
no chance of winning.

