With the release of Scala 2.9.0, the Typesafe Stack was also announced, which combines the Scala language with the Akka framework. Now, though Scala has actors in its standard library, Akka uses its own implementation. And, if we look for other implementations, we'll also find that Lift and Scalaz have implementations too!
So, what is the difference between these implementations?
This answer isn't really mine. It was produced by Viktor Klang (of Akka fame) with the help of David Pollak (of Lift fame), Jason Zaugg (of Scalaz fame), Philipp Haller (of Scala Actors fame).
All I'm doing here is formatting it (which would be easier if Stack Overflow supported tables).
There are a few places I'll fill later when I have more time.
Design Philosophy
Scalaz Actors
Minimal complexity. Maximal generality, modularity and extensibility.
Lift Actors
Minimal complexity, Garbage Collection by JVM rather than worrying about an explicit lifecycle, error handling behavior consistent with other Scala & Java programs, lightweight/small memory footprint, mailbox, statically similar to Scala Actors and Erlang actors, high performance.
Scala Actors
Provide the full Erlang actor model in Scala, lightweight/small memory footprint.
Akka Actors
Simple and transparently distributable, high performance, lightweight and highly adaptable.
Versioning
Scalaz Actors Lift Actors Scala Actors Akka Actors
Current stable ver. 5 2.1 2.9.0 0.10
Minimum Scala ver. 2.8 2.7.7 2.8
Minimum Java ver. 1.5 1.5 1.6
Actor Model Support
Scalaz Actors Lift Actors Scala Actors Akka Actors
Spawn new actors Yes Yes Yes Yes
inside of actor
Send messages to Yes Yes Yes Yes
known actor
Change behavior Actors are Yes Yes: nested Yes:
for next message immutable react/receive become/unbecome
Supervision Not provided No Actor: Yes, Yes
(link/trapExit) Reactor: No
Level of state isolation
If user defines public methods on
their Actors, are they callable from
the outside?
- Scalaz Actors: n/a. Actor is a sealed trait.
- Lift Actors: Yes
- Scala Actors: Yes
- Akka Actors: No, actor instance is shielded behind an ActorRef.
Actor type
- Scalaz Actors:
Actor[A] extends A => ()
- Lift Actors:
LiftActor
, SpecializeLiftActor[T]
- Scala Actors:
Reactor[T]
, Actor extends Reactor[Any]
- Akka Actors:
Actor[Any]
Actor lifecycle management
Scalaz Actors Lift Actors Scala Actors Akka Actors
Manual start No No Yes Yes
Manual stop No No No Yes
Restart-on-failure n/a Yes Yes Configurable per actor instance
Restart semantics n/a Rerun actor Restore actor to stable state by re-allocating it and
behavior throw away the old instance
Restart configurability n/a n/a X times, X times within Y time
Lifecycle hooks provided No lifecycle act preStart, postStop, preRestart, postRestart
Message send modes
Scalaz Actors Lift Actors Scala Actors Akka Actors
Fire-forget a ! message actor ! msg actor ! msg actorRef ! msg
a(message)
Send-receive-reply (see 1) actor !? msg actor !? msg actorRef !! msg
actor !! msg
Send-receive-future (see 2) actor !! msg actorRef !!! msg
Send-result-of- promise(message). future.onComplete( f => to ! f.result )
future to(actor)
Compose actor with actor comap f No No No
function (see 3)
(1) Any function f becomes such an actor:
val a: Msg => Promise[Rep] = f.promise
val reply: Rep = a(msg).get
(2) Any function f becomes such an actor:
val a = f.promise
val replyFuture = a(message)
(3) Contravariant functor: actor comap f
. Also Kleisli composition in Promise
.
Message reply modes
TBD
Scalaz Actors Lift Actors Scala Actors Akka Actors
reply-to-sender-in-message
reply-to-message
Message processing
Supports nested receives?
- Scalaz Actors: --
- Lift Actors: Yes (with a little hand coding).
- Scala Actors: Yes, both thread-based receive and event-based react.
- Akka Actors: No, nesting receives can lead to memory leaks and degraded performance over time.
Message Execution Mechanism
TBD
Scalaz Actors Lift Actors Scala Actors Akka Actors
Name for Execution Mechanism
Execution Mechanism is
configurable
Execution Mechanism can be
specified on a per-actor basis
Lifecycle of Execution Mechanism
must be explicitly managed
Thread-per-actor execution
mechanism
Event-driven execution mechanism
Mailbox type
Supports transient mailboxes
Supports persistent mailboxes
Distribution/Remote Actors
Scalaz Actors Lift Actors Scala Actors Akka Actors
Transparent remote n/a No Yes Yes
actors
Transport protocol n/a n/a Java Akka Remote Protocol
serialization (Protobuf on top of TCP)
on top of TCP
Dynamic clustering n/a n/a n/a In commercial offering
Howtos
TBD
Scalaz Actors Lift Actors Scala Actors Akka Actors
Define an actor
Create an actor instance
Start an actor instance
Stop an actor instance
Actors: Scala 2.10 vs Akka 2.3 vs Lift 2.6 vs Scalaz 7.1
Test code & results for average latency and throughput on JVM 1.8.0_x.