actor-based concurrency and akka fundamentals
DESCRIPTION
TRANSCRIPT
Actor-based concurrency and AkkaFundamentals
Bon Festival 2014Ngoc Dao
Benefit of actor in one sentence
C vs Java:You can use memory without having to free memory.
Thread vs actor:You can use concurrency without having to create threads.
Don't communicate by sharing memory;share memory by communicating.
Actor model
● Actor = states + mailbox + behaviors (msg handlers)
● From outside, can’t manipulate actors directly.● To interact with an actor, must send msgs to it.● Each actor has a mailbox, msgs are put to mailbox, and
processed one by one. ← An actor is like a single threaded process; it doesn’t do more than one thing at a time.
http://www.cs.tsukuba.ac.jp/~yas/cs/csys-2013/2013-12-03/
Concurrency: Actor vs ThreadThread:● Heavy weight: Can only create not too many threads;
usually: 2000~5000● Shared state ← Source of bugs● Passive: Have to call object.method() to make the
object alive.
Actor:● Light weight: Can create millions of actors;
usually: ~2.5 million actors/GB● Shared nothing● Active: Actors are alive by themselves. ← Easy to
model programs that have millions of on-going things (very high level of concurrency), like MMOG games.
Concurrency: Actor vs Thread
● Thread: n dimensions, hard to reason about.● Actor: 1D, one thing at a time.
var1
var2
● Actor is a high level logical way to think, to model programs.
● At lower level, actors run above a thread pool.
Concurrency: Actor vs Thread
Akka: Demo
● Live coding demo
Demo: Counter
// First, define messagesobject Counter { case class Inc(amount: Int) case class Dec(amount: Int)}
import akka.actor.Actor
// Define actor state and msg handlerclass Counter(name: String) extends Actor { // Actor state private var value = 0
override def preStart() { println(s"I'm alive: $name") }
override def postStop() { println(s"I'm dead: $name") } ...
...
import Counter._
// Msg handler def receive = { case Inc(amount) => value += amount println(s"Value: $value")
case Dec(amount) => value -= amount println(s"Value: $value") }}
import akka.actor.{ActorSystem, Props}
// Think of this as a thread poolval system = ActorSystem("mysystem")
// Create actor reference (instance)val c1 = system.actorOf( Props(new Counter("mylock")))
// Send messages to the actorc1 ! Counter.Inc(1)c1 ! Counter.Dec(2)
Demo: Behavior transition
CodeLock:https://github.com/ngocdaothanh/code-lock-fsm-akka
Some actor antipatterns
Send mutable msgs between actors.← May lead to bug, if actor A sends msg M to actor B, state of B incorporates M, then M is later changed by A.
Fix: Use immutable msgs.
From inside actor:outsideObject.foo(new Callback { def onCallback() { directlyModifyActorState() }}) ← May lead to bug, because the actor’s thread and the callback’s thread may be 2 different threads. Remember: An actor is like a single threaded process, can’t do more than one thing at a time.
Fix: self ! msgFromCallback
Some actor antipatterns
References
● Concurrent Programming for Scalable Web Architectureshttp://berb.github.io/diploma-thesis/index.html
● Functions + Messages + Concurrency = Erlanghttp://www.infoq.com/presentations/joe-armstrong-erlang-qcon08
● Akka dochttp://doc.akka.io/docs/akka/2.3.5/scala.html