Akka Actor
Introduction
Gene
Akka
The name comes from the goddess in the Sami
(Native swedes) mythology that represents all
the wisdom and beauty in the world. It’s also the
name of a beautiful mountain in Laponia in the
north part of Sweden.
Akka
Agenda
1. Akka Introduction
2. Core Operations
3. WebSocket with Actor
4. Remote Actor
Typesafe
Toolkit/Library(*.jar)
Programming Language
Web Application Framework
Scala
• Functional as well as Object-Oriented
• Scala is compatible with Java
• Scala is compiled to Java byte-codes and run on Java Virtual Machine
Java
Scala
1.Akka Introduction
Akka
•一個 JVM 上 Actor Model 的實作
1. Concurrency
2. Distribution
3. Fault-tolerance
Actors
Remoting
Supervision
Object Actor
Java AKKA
Object
Java AKKA
Object MailboxMailbox
Message
Message
Message
Concurrent programming
Concurrent
Parallel
Java
Thread Thread
Shared
Memory
R/W R/W
Java
Thread Thread
Shared
Memory
Locks Waits
Java
Thread Thread
Shared
Memory
Shared
Memory
Locks
Locks
Waits
Waits
Dead Lock !
How to avoid?
Shared state
Java
Threads
Lockers
Global variables,
Static variables
Java
implements
Runnable{}
synchronized(lock);….
Global variables,
Static variables
Java
implements
Runnable{}
synchronized(lock);….
Immutable object
Wait()/Notify()/NofifyALL()
Thread Safe
AKKA
Actor Actor
Actor
Message
Message
Message
Java
Global variables,
Static variables
implements
Runnable{}
synchronized(lock);….
Immutable object
Wait()/Notify()/NofifyALL()
Thread Safe
AKKA
Message flow
Java
Global variables,
Static variables
implements
Runnable{}
synchronized(lock);….
Immutable object
Wait()/Notify()/NofifyALL()
Thread Safe
Actor
MailboxMailbox
State
Message
Message
Message
Actor having
1. Behavior (Processing)
2. State (Storage)
3. Mailbox (Message Queue)
*State is not shared, only accessible
through…messages passing.
Behavior
Messages are in mailbox.
Actor
MailboxMailbox
Behavior
State
Message
Message
Message
Actor
MailboxMailbox
Thread is allocated to the Actor.
 It has read message and is applying
behavior (in OnReceive() function).
Behavior
State Message
Message
Message
AKKA
 Actor has handled message*.
Thread is deallocated.
*One message is executed at a time
& messages are processed sequentially .
MailboxMailbox
Message
Message
Behavior
State
Dispatcher
Dispatcher
4 types of dispatchers
1. Dispatcher (default)
2. Pinned dispatcher
3. Balancing dispatcher (Deprecated*)
4. Calling thread dispatcher
*Instead by BalancingPool of Router.
Router
Router Types
• RoundRobinPool & RoundRobinGroup
• RandomPool & RandomGroup
• BalancingPool- shared mailbox
• SmallestMailboxPool
• BroadcastPool & BroadcastGroup
• ScatterGatherFirstCompletedPool & ScatterGatherFirstCompletedGroup
• TailChoppingPool & TailChoppingGroup
• ConsistentHashingPool & ConsistentHashingGroup
2.Core Operations
5 Core Actor Operations
0. Define → Define Actors
1. Create → Create new Actors
2. Send → Send messages to other Actors
3. Become → Change the behavior for handling the next message
4. Supervise → Manage another Actors failure
0.DEFINE
import akka.actor.UntypedActor;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import akka.japi.Procedure;
public class AnActor extends UntypedActor {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
public void onReceive(Object message){
if (message instanceof String) {
log.info((String) message);
}else{
unhandled(message);
log.info("Unhandled message");
}
}
}
package controllers;
import akka.actor.ActorRef;
import akka.actor.Props;
import play.libs.Akka;
import play.mvc.*;
public class HelloActor extends Controller {
public static Result index() {
ActorRef actor = Akka.system().actorOf(Props.create(AnActor.class));
// insert stuff actor.tell(message)
return ok("ok");
}
}
1.CREATE
package controllers;
import akka.actor.ActorRef;
import akka.actor.Props;
import play.libs.Akka;
import play.mvc.*;
public class HelloActor extends Controller {
public static Result index() {
ActorRef actor = Akka.system().actorOf(Props.create(AnActor.class));
actor.tell("Hello Actor!!", null);
return ok("ok");
}
}
2.SEND
[INFO] [03/13/2015 22:14:01.442] [application-akka.actor.default-dispatcher-2] [akka://application/user/$a] Hello Actor!!
3 ways to sending messages
1. Fire-Forget
2. Ask and Reply
3. Forward
 Tell
 Ask
 Forward
Tell
Target.tell(message, sender);
ActorRef ActorRefObject
1. null
2. ActorRef.noSender()
3. getSelf()
4. …
A Bmessage
1. To send a message to an actor, you need a Actor reference
2. Asynchronous and Non-blocking (Fire-and-forget)
Target
Target.tell(message, sender);
Tell
public void onReceive(Object message){
if (message instanceof String) {
log.info((String) message);
log.info("getSender()="+getSender());
}
}
A Bmessage
Target
Tell
ActorRef ActorRefObject
A Bmessage
B.tell(new Person(“David”,”Chang”),getSelf());
EXAMPLE:
B.tell(“Hello Actor”,ActorRef.noSender());
Target.tell(message, sender);
Target
Ask
Future<Object> rt = Patterns.ask(Target, message, timeout);
A B
message
reply
getSender().tell(reply_message, getSelf());
String result = Await.result(rt , timeout.duration);
1
2
3
Target
import scala.concurrent.Await;
import scala.concurrent.Future;
import scala.concurrent.duration.Duration;
public class HelloActor extends Controller {
public static Result index() {
ActorRef actor = Akka.system().actorOf(Props.create(AnActor.class));
final Timeout timeout = new Timeout(Duration.create(1, SECONDS));
Future<Object> rt = Patterns.ask(actor,"What's your name?", timeout);
try {
String result = (String) Await.result(rt, timeout.duration());
System.out.println("The name is "+result);
return ok("The name is "+result);
} catch (Exception e) {
System.out.println(e);
}
return ok("");
}
}
Ask
The Name is David
import akka.actor.UntypedActor;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import akka.japi.Procedure;
public class AnActor extends UntypedActor {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
public void onReceive(Object message){
if(message.equals("What's your name?")){
getSender().tell("David",getSelf());
}else
if (message instanceof String) {
log.info((String ) message);
}else{
unhandled(message);
log.info("Unhandled message");
}
}
}
Ask
The Name is David
Forward
ActorContext
A B
forward
Target.forward(message, getContext());
C
Target.tell(message, getSender());
ActorRef
Target
3.BECOME
getContext().become(Procedure<Object>);
1.Dynamically redefines actor behavior
2.Reactively triggered by message
3.Behaviors are stacked & can be pushed and popped
 getContext().unbecome();
BECOME
public class HotSwapActor extends UntypedActor {
Procedure<Object> angry = new Procedure<Object>() {
@Override
public void apply(Object message) {
if (message.equals(“work")) {
getSender().tell(“I am angry ",getSelf());
} else if (message.equals(“play")) {
getContext().become(happy);
}
}
};
Procedure<Object> happy = new Procedure<Object>() {
@Override
public void apply(Object message) {
if (message.equals(“play")) {
getSender().tell("I am happy ", getSelf());
} else if (message.equals(“work")) {
getContext().become(angry);
}
}
};
public void onReceive(Object message) {
if (message.equals(“work")) {
getContext().become(angry);
} else if (message.equals(“play")) {
getContext().become(happy);
} else {
unhandled(message);
}
}
}
public void onReceive(Object message)
{
if (message.equals(“work")) {
getContext().become(angry);
}
else if (message.equals(“play")){
getContext().become(happy);
} else {
unhandled(message);
}
}
}
public class HotSwapActor extends UntypedActor {
Procedure<Object> angry = new Procedure<Object>() {
@Override
public void apply(Object message) {
if (message.equals(“work")) {
getSender().tell(“I am angry ",getSelf());
} else if (message.equals(“play")) {
getContext().become(happy);
}
}
};
Procedure<Object> happy = new Procedure<Object>() {
@Override
public void apply(Object message) {
if (message.equals(“play")) {
getSender().tell("I am happy ", getSelf());
} else if (message.equals(“work")) {
getContext().become(angry);
}
}
};
public void onReceive(Object message) {
if (message.equals(“work")) {
getContext().become(angry);
} else if (message.equals(“play")) {
getContext().become(happy);
} else {
unhandled(message);
}
}
}
BECOME
Procedure<Object> angry = new Procedure<Object>() {
@Override
public void apply(Object message) {
if (message.equals(“work")) {
getSender().tell("I am angry ", getSelf());
} else if (message.equals(“play")) {
getContext().become(happy);
}
}
};
Hierarchy
• Actors can form hierarchies
Akka System
Default Actor
Supervisor
Actor
Child
Actor
ActorRef supervisor = Akka.system().actorOf(Props.create(SupervisorActor.class), “Supervisor”);
ActorRef child = getContext().actorOf(Props.create(ChildActor.class), “Child”);
akka://application/user
akka://application/user/Supervisor
akka://application/user/Supervisor/Child
parent
child
3.WebSocket with Actor
PlayFramework 2
WebSocket with Actor
Actor
WebSocket Actor
messages
Client
websocketHTTP
WebSocket with Actor
• Controller
• Routes
• URL
import play.mvc.WebSocket;
public class Application extends Controller {
public static WebSocket<JsonNode> chat(final String username) {
return WebSocket.withActor(new Function<ActorRef, Props>() {
public Props apply(ActorRef out) throws Throwable {
return ChatWebSocketActor.props(out, username);
}
});
}
}
GET /room/chat controllers.Application.chat(username)
ws://127.0.0.1:9000/room/chat?username=XXX
public class ChatWebSocketActor extends UntypedActor {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
public static Props props(ActorRef out, String username) {
return Props.create(ChatWebSocketActor.class, out, username);
}
private final ActorRef out;
private final String username;
public ChatWebSocketActor(ActorRef out,String username) {
this.out = out;
this.username = username;
}
public void preStart(){
//do something
}
public void onReceive(Object message) throws Exception {
//do something
}
public void postStop() throws Exception {
//do something
}
}
WebSocket with Actor
Receive websocket message
WebSocket with Actor
out
handler
akka://application/system/websockets/123
akka://application/system/websockets/123/handler
parent
child
Send websocket message
Receive websocket message
In child: getContext().parnet()
WebSocket with Actor
• Send websocket message to client
• Closing a websocket
out.tell(message, null);
out
handler
out.tell(PoisonPill.getInstance(), self());
WebSocket Actors
Chat Actor
out
handler
out
handler
out
handler
out
handler
Chat
Client-1 Client-2 Client-3 Client-4
websocket
messages
WebSocket Actors
Chat flow – (1)
out
handler
out
handler
out
handler
out
handler
Chat
Client-1 Client-2 Client-3 Client-4
websocket
WebSocket Actors
Chat flow – (2)
out
handler
out
handler
out
handler
out
handler
Chat
Client-1 Client-2 Client-3 Client-4
message
WebSocket Actors
Chat flow – (3)
out
handler
out
handler
out
handler
out
handler
Chat
Client-1 Client-2 Client-3 Client-4
websocket
4.Remote Actor
Remote Actors
Actor
B
messageActor
A
192.168.0.2192.168.0.1
 akka.tcp://application@192.168.0.1/user/ActorA  akka.tcp://application@192.168.0.2/user/ActorB
Preparing your ActorSystem for Remoting
Akka System
Default Actor
Supervisor
Actor
Child
Actor
akka://application/user
akka://application/user/Supervisor
akka://application/user/Supervisor/Child
akka://application@127.0.0.1/user
akka://application@127.0.0.1/user/Supervisor
akka://application@127.0.0.1/user/Supervisor/Child
Local Path Remote Path
•Each Actor has a Path, but an ActorSystem can be publish in an Address.
Preparing your ActorSystem for Remoting
akka {
actor {
provider = "akka.remote.RemoteActorRefProvider"
}
remote {
enabled-transports = ["akka.remote.netty.tcp"]
netty.tcp {
hostname = "127.0.0.1"
port = 7100
}
}
}
Play Framework
AKKA
Port 7100
Port 7000Web
Remote Actors
Play Framework 2 Play Framework 2
Client
Actor
B
Controller
View
HTTP GET
What’s your name?
Gene
The name is Gene
Reponse  akka.tcp://application@127.0.0.1:7100/user/ActorB
Send Messages to Remote Actors
ActorSelection selection =
Akka.system().actorSelection("akka.tcp://application@127.0.0.1:7100/user/ActorB");
selection.tell("Hello Remote",null);
Future<Object> rt = Patterns.ask(selection,"What's your name?", timeout);
Retrieve remote actor
Tell message
Ask message
Creating Actor Remotely
remote
Actor
CreateActor
A
192.168.0.2192.168.0.1
 akka.tcp://application@192.168.0.1/user/ActorA  akka.tcp://application@192.168.0.2/user/ActorB
Server A Server B
Creating Actor Remotely – How to create?
remote
Actor
CreateActor
A
 Both server must have same Actor class to be remote
Server A Server B
1
Remote
Actor
Create
Actor
A
akka {
actor {
provider = "akka.remote.RemoteActorRefProvider“
deployment {
/remoteActor {
remote = "akka.tcp://application@127.0.0.1:9100"
}
}
}
remote {
enabled-transports = ["akka.remote.netty.tcp"]
netty.tcp {
hostname = "127.0.0.1"
port = 7100
}
}
}
akka {
actor {
provider = "akka.remote.RemoteActorRefProvider
}
remote {
enabled-transports = ["akka.remote.netty.tcp"]
netty.tcp {
hostname = "127.0.0.1"
port = 9100
}
}
}
for server A for server B
2  Amend the application.conf file for Server A
Server A Server B
Creating Actor Remotely – How to create?
remote
Actor
CreateActor
A
 Use actorOf () to create a remote actor on Server A.
Server A Server B
3
ActorRef actor = Akka.system().actorOf(Props.create(remoteActor.class), "remoteActor");
actor.tell("Hello Remote",null);
Another way to Create Actor Remotely
import akka.actor.ActorSelection;
import akka.actor.Address;
import akka.actor.AddressFromURIString;
import akka.actor.Deploy;
import akka.remote.RemoteScope;
public class HelloActor extends Controller {
public static Result index() {
Address addr = AddressFromURIString.parse("akka.tcp://application@127.0.0.1:9100");
ActorRef actor = Akka.system().actorOf(Props.create(remoteActor.class).withDeploy(
new Deploy(new RemoteScope(addr))));
actor.tell("Hello Remote",null);
}
}
for server A
Remote Actors
name := """hello2"""
version := "1.0-SNAPSHOT"
lazy val root = (project in file(".")).enablePlugins(PlayJava)
scalaVersion := "2.11.1"
libraryDependencies ++= Seq(
javaJdbc,
javaEbean,
cache,
javaWs
)
libraryDependencies += "com.typesafe.akka" %% "akka-remote" % "2.3.9"
THANKS

Akka Actor presentation

  • 1.
  • 2.
    Akka The name comesfrom the goddess in the Sami (Native swedes) mythology that represents all the wisdom and beauty in the world. It’s also the name of a beautiful mountain in Laponia in the north part of Sweden. Akka
  • 3.
    Agenda 1. Akka Introduction 2.Core Operations 3. WebSocket with Actor 4. Remote Actor
  • 4.
  • 5.
    Scala • Functional aswell as Object-Oriented • Scala is compatible with Java • Scala is compiled to Java byte-codes and run on Java Virtual Machine
  • 6.
  • 7.
  • 9.
    Akka •一個 JVM 上Actor Model 的實作 1. Concurrency 2. Distribution 3. Fault-tolerance Actors Remoting Supervision
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
    AKKA Actor Actor Actor Message Message Message Java Global variables, Staticvariables implements Runnable{} synchronized(lock);…. Immutable object Wait()/Notify()/NofifyALL() Thread Safe
  • 21.
    AKKA Message flow Java Global variables, Staticvariables implements Runnable{} synchronized(lock);…. Immutable object Wait()/Notify()/NofifyALL() Thread Safe
  • 22.
    Actor MailboxMailbox State Message Message Message Actor having 1. Behavior(Processing) 2. State (Storage) 3. Mailbox (Message Queue) *State is not shared, only accessible through…messages passing. Behavior
  • 23.
    Messages are inmailbox. Actor MailboxMailbox Behavior State Message Message Message
  • 24.
    Actor MailboxMailbox Thread is allocatedto the Actor.  It has read message and is applying behavior (in OnReceive() function). Behavior State Message Message Message
  • 25.
    AKKA  Actor hashandled message*. Thread is deallocated. *One message is executed at a time & messages are processed sequentially . MailboxMailbox Message Message Behavior State
  • 26.
  • 27.
  • 28.
    4 types ofdispatchers 1. Dispatcher (default) 2. Pinned dispatcher 3. Balancing dispatcher (Deprecated*) 4. Calling thread dispatcher *Instead by BalancingPool of Router.
  • 29.
  • 30.
    Router Types • RoundRobinPool& RoundRobinGroup • RandomPool & RandomGroup • BalancingPool- shared mailbox • SmallestMailboxPool • BroadcastPool & BroadcastGroup • ScatterGatherFirstCompletedPool & ScatterGatherFirstCompletedGroup • TailChoppingPool & TailChoppingGroup • ConsistentHashingPool & ConsistentHashingGroup
  • 31.
  • 32.
    5 Core ActorOperations 0. Define → Define Actors 1. Create → Create new Actors 2. Send → Send messages to other Actors 3. Become → Change the behavior for handling the next message 4. Supervise → Manage another Actors failure
  • 33.
    0.DEFINE import akka.actor.UntypedActor; import akka.event.Logging; importakka.event.LoggingAdapter; import akka.japi.Procedure; public class AnActor extends UntypedActor { LoggingAdapter log = Logging.getLogger(getContext().system(), this); public void onReceive(Object message){ if (message instanceof String) { log.info((String) message); }else{ unhandled(message); log.info("Unhandled message"); } } }
  • 34.
    package controllers; import akka.actor.ActorRef; importakka.actor.Props; import play.libs.Akka; import play.mvc.*; public class HelloActor extends Controller { public static Result index() { ActorRef actor = Akka.system().actorOf(Props.create(AnActor.class)); // insert stuff actor.tell(message) return ok("ok"); } } 1.CREATE
  • 35.
    package controllers; import akka.actor.ActorRef; importakka.actor.Props; import play.libs.Akka; import play.mvc.*; public class HelloActor extends Controller { public static Result index() { ActorRef actor = Akka.system().actorOf(Props.create(AnActor.class)); actor.tell("Hello Actor!!", null); return ok("ok"); } } 2.SEND [INFO] [03/13/2015 22:14:01.442] [application-akka.actor.default-dispatcher-2] [akka://application/user/$a] Hello Actor!!
  • 36.
    3 ways tosending messages 1. Fire-Forget 2. Ask and Reply 3. Forward  Tell  Ask  Forward
  • 37.
    Tell Target.tell(message, sender); ActorRef ActorRefObject 1.null 2. ActorRef.noSender() 3. getSelf() 4. … A Bmessage 1. To send a message to an actor, you need a Actor reference 2. Asynchronous and Non-blocking (Fire-and-forget) Target
  • 38.
    Target.tell(message, sender); Tell public voidonReceive(Object message){ if (message instanceof String) { log.info((String) message); log.info("getSender()="+getSender()); } } A Bmessage Target
  • 39.
    Tell ActorRef ActorRefObject A Bmessage B.tell(newPerson(“David”,”Chang”),getSelf()); EXAMPLE: B.tell(“Hello Actor”,ActorRef.noSender()); Target.tell(message, sender); Target
  • 40.
    Ask Future<Object> rt =Patterns.ask(Target, message, timeout); A B message reply getSender().tell(reply_message, getSelf()); String result = Await.result(rt , timeout.duration); 1 2 3 Target
  • 41.
    import scala.concurrent.Await; import scala.concurrent.Future; importscala.concurrent.duration.Duration; public class HelloActor extends Controller { public static Result index() { ActorRef actor = Akka.system().actorOf(Props.create(AnActor.class)); final Timeout timeout = new Timeout(Duration.create(1, SECONDS)); Future<Object> rt = Patterns.ask(actor,"What's your name?", timeout); try { String result = (String) Await.result(rt, timeout.duration()); System.out.println("The name is "+result); return ok("The name is "+result); } catch (Exception e) { System.out.println(e); } return ok(""); } } Ask The Name is David
  • 42.
    import akka.actor.UntypedActor; import akka.event.Logging; importakka.event.LoggingAdapter; import akka.japi.Procedure; public class AnActor extends UntypedActor { LoggingAdapter log = Logging.getLogger(getContext().system(), this); public void onReceive(Object message){ if(message.equals("What's your name?")){ getSender().tell("David",getSelf()); }else if (message instanceof String) { log.info((String ) message); }else{ unhandled(message); log.info("Unhandled message"); } } } Ask The Name is David
  • 43.
  • 44.
    3.BECOME getContext().become(Procedure<Object>); 1.Dynamically redefines actorbehavior 2.Reactively triggered by message 3.Behaviors are stacked & can be pushed and popped  getContext().unbecome();
  • 45.
    BECOME public class HotSwapActorextends UntypedActor { Procedure<Object> angry = new Procedure<Object>() { @Override public void apply(Object message) { if (message.equals(“work")) { getSender().tell(“I am angry ",getSelf()); } else if (message.equals(“play")) { getContext().become(happy); } } }; Procedure<Object> happy = new Procedure<Object>() { @Override public void apply(Object message) { if (message.equals(“play")) { getSender().tell("I am happy ", getSelf()); } else if (message.equals(“work")) { getContext().become(angry); } } }; public void onReceive(Object message) { if (message.equals(“work")) { getContext().become(angry); } else if (message.equals(“play")) { getContext().become(happy); } else { unhandled(message); } } } public void onReceive(Object message) { if (message.equals(“work")) { getContext().become(angry); } else if (message.equals(“play")){ getContext().become(happy); } else { unhandled(message); } } }
  • 46.
    public class HotSwapActorextends UntypedActor { Procedure<Object> angry = new Procedure<Object>() { @Override public void apply(Object message) { if (message.equals(“work")) { getSender().tell(“I am angry ",getSelf()); } else if (message.equals(“play")) { getContext().become(happy); } } }; Procedure<Object> happy = new Procedure<Object>() { @Override public void apply(Object message) { if (message.equals(“play")) { getSender().tell("I am happy ", getSelf()); } else if (message.equals(“work")) { getContext().become(angry); } } }; public void onReceive(Object message) { if (message.equals(“work")) { getContext().become(angry); } else if (message.equals(“play")) { getContext().become(happy); } else { unhandled(message); } } } BECOME Procedure<Object> angry = new Procedure<Object>() { @Override public void apply(Object message) { if (message.equals(“work")) { getSender().tell("I am angry ", getSelf()); } else if (message.equals(“play")) { getContext().become(happy); } } };
  • 47.
    Hierarchy • Actors canform hierarchies Akka System Default Actor Supervisor Actor Child Actor ActorRef supervisor = Akka.system().actorOf(Props.create(SupervisorActor.class), “Supervisor”); ActorRef child = getContext().actorOf(Props.create(ChildActor.class), “Child”); akka://application/user akka://application/user/Supervisor akka://application/user/Supervisor/Child parent child
  • 48.
  • 49.
    PlayFramework 2 WebSocket withActor Actor WebSocket Actor messages Client websocketHTTP
  • 50.
    WebSocket with Actor •Controller • Routes • URL import play.mvc.WebSocket; public class Application extends Controller { public static WebSocket<JsonNode> chat(final String username) { return WebSocket.withActor(new Function<ActorRef, Props>() { public Props apply(ActorRef out) throws Throwable { return ChatWebSocketActor.props(out, username); } }); } } GET /room/chat controllers.Application.chat(username) ws://127.0.0.1:9000/room/chat?username=XXX
  • 51.
    public class ChatWebSocketActorextends UntypedActor { LoggingAdapter log = Logging.getLogger(getContext().system(), this); public static Props props(ActorRef out, String username) { return Props.create(ChatWebSocketActor.class, out, username); } private final ActorRef out; private final String username; public ChatWebSocketActor(ActorRef out,String username) { this.out = out; this.username = username; } public void preStart(){ //do something } public void onReceive(Object message) throws Exception { //do something } public void postStop() throws Exception { //do something } } WebSocket with Actor Receive websocket message
  • 52.
  • 53.
    WebSocket with Actor •Send websocket message to client • Closing a websocket out.tell(message, null); out handler out.tell(PoisonPill.getInstance(), self());
  • 54.
  • 55.
    WebSocket Actors Chat flow– (1) out handler out handler out handler out handler Chat Client-1 Client-2 Client-3 Client-4 websocket
  • 56.
    WebSocket Actors Chat flow– (2) out handler out handler out handler out handler Chat Client-1 Client-2 Client-3 Client-4 message
  • 57.
    WebSocket Actors Chat flow– (3) out handler out handler out handler out handler Chat Client-1 Client-2 Client-3 Client-4 websocket
  • 58.
  • 59.
  • 60.
    Preparing your ActorSystemfor Remoting Akka System Default Actor Supervisor Actor Child Actor akka://application/user akka://application/user/Supervisor akka://application/user/Supervisor/Child akka://application@127.0.0.1/user akka://application@127.0.0.1/user/Supervisor akka://application@127.0.0.1/user/Supervisor/Child Local Path Remote Path •Each Actor has a Path, but an ActorSystem can be publish in an Address.
  • 61.
    Preparing your ActorSystemfor Remoting akka { actor { provider = "akka.remote.RemoteActorRefProvider" } remote { enabled-transports = ["akka.remote.netty.tcp"] netty.tcp { hostname = "127.0.0.1" port = 7100 } } } Play Framework AKKA Port 7100 Port 7000Web
  • 62.
    Remote Actors Play Framework2 Play Framework 2 Client Actor B Controller View HTTP GET What’s your name? Gene The name is Gene Reponse  akka.tcp://application@127.0.0.1:7100/user/ActorB
  • 63.
    Send Messages toRemote Actors ActorSelection selection = Akka.system().actorSelection("akka.tcp://application@127.0.0.1:7100/user/ActorB"); selection.tell("Hello Remote",null); Future<Object> rt = Patterns.ask(selection,"What's your name?", timeout); Retrieve remote actor Tell message Ask message
  • 64.
    Creating Actor Remotely remote Actor CreateActor A 192.168.0.2192.168.0.1 akka.tcp://application@192.168.0.1/user/ActorA  akka.tcp://application@192.168.0.2/user/ActorB Server A Server B
  • 65.
    Creating Actor Remotely– How to create? remote Actor CreateActor A  Both server must have same Actor class to be remote Server A Server B 1
  • 66.
    Remote Actor Create Actor A akka { actor { provider= "akka.remote.RemoteActorRefProvider“ deployment { /remoteActor { remote = "akka.tcp://application@127.0.0.1:9100" } } } remote { enabled-transports = ["akka.remote.netty.tcp"] netty.tcp { hostname = "127.0.0.1" port = 7100 } } } akka { actor { provider = "akka.remote.RemoteActorRefProvider } remote { enabled-transports = ["akka.remote.netty.tcp"] netty.tcp { hostname = "127.0.0.1" port = 9100 } } } for server A for server B 2  Amend the application.conf file for Server A Server A Server B
  • 67.
    Creating Actor Remotely– How to create? remote Actor CreateActor A  Use actorOf () to create a remote actor on Server A. Server A Server B 3 ActorRef actor = Akka.system().actorOf(Props.create(remoteActor.class), "remoteActor"); actor.tell("Hello Remote",null);
  • 68.
    Another way toCreate Actor Remotely import akka.actor.ActorSelection; import akka.actor.Address; import akka.actor.AddressFromURIString; import akka.actor.Deploy; import akka.remote.RemoteScope; public class HelloActor extends Controller { public static Result index() { Address addr = AddressFromURIString.parse("akka.tcp://application@127.0.0.1:9100"); ActorRef actor = Akka.system().actorOf(Props.create(remoteActor.class).withDeploy( new Deploy(new RemoteScope(addr)))); actor.tell("Hello Remote",null); } } for server A
  • 69.
    Remote Actors name :="""hello2""" version := "1.0-SNAPSHOT" lazy val root = (project in file(".")).enablePlugins(PlayJava) scalaVersion := "2.11.1" libraryDependencies ++= Seq( javaJdbc, javaEbean, cache, javaWs ) libraryDependencies += "com.typesafe.akka" %% "akka-remote" % "2.3.9"
  • 70.

Editor's Notes

  • #3 Akka的名字由來:akka是瑞典一座山的名字,也是瑞典一個神話中的女神的名字,那山被看成那個女神的化身。所以akka的logo就是一座山。akka中的A,K正好表示Actor Kernel
  • #5 Why Scala, Play and Akka? Scala is a modern JVM language with support for many features such as Functional Programming & Immutability Concurrency—features that aid in enabling highly scalable web apps & backends. After years of Java development, we have experienced a continuous demand for web applications & APIs which are responsive, concurrent, and reactive. Scala brings together the type safety of Java and the expressivity and productivity you would expect to find in popular dynamic languages such as Ruby. What does this mean? Scala reduces the boilerplate generally associated with large Java projects. Our developers can focus more on app development while leveraging the powerful features provided by Scala. Play Framework brings a stateless model which enables asynchronous highly scalable concurrent transactions in web systems with a simple and concise API. We have extensive experience providing mission critical applications that run on EC2 and Heroku for customers in diverse sectors such as finances, travel and entertaiment industries. Through this experience, we have found that applications built on Scala and Play are extremely reliable in production— scaling horizontally on both the cloud and a cluster of affordable commodity hardware. Akka is the middleware that enables asynchronous operations in tightly packed fault tolerant architecture ideal to model complex business processes and jobs based on the popular Actor pattern.
  • #10 並行,分散性,容錯性高 Introduction of Akka Akka 是多工運算的框架,用 Scala 撰寫,也有支援 Java API。Akka 最主要的目的是要解決 Synchronize 造成的效能問題,以及可能發生的 Dead-Lock 問題。 相關資料: [Akka 官方資料] (http://akka.io/docs/) Typesafe 的 Activator 特性 Non-Blocking and Asynchronous 所有 Akka 上的運作都是 Non-Blocking,
  • #12 Message Queue
  • #15 http://typesafe.com/activator/template/hello-akka
  • #16 http://typesafe.com/activator/template/hello-akka
  • #17 http://typesafe.com/activator/template/hello-akka
  • #18 http://typesafe.com/activator/template/hello-akka
  • #19 http://typesafe.com/activator/template/hello-akka
  • #20 http://typesafe.com/activator/template/hello-akka http://kalmanb.com/slides/2014-scala-downunder/akka.html#/1/2 http://markusjura.github.io/akka-intro-slides/#/8
  • #21 http://typesafe.com/activator/template/hello-akka http://kalmanb.com/slides/2014-scala-downunder/akka.html#/1/2 http://markusjura.github.io/akka-intro-slides/#/8
  • #22 An active entity with an Inbox = Queue A State  =  Storage State is not shared, only accessible through... ...messages passing one message is executed at a time messages are processed sequentially 
  • #23 Processing → Behavior Storage → State
  • #24 Processing → Behavior Storage → State
  • #25 Message Queue
  • #26 Message Queue
  • #29 Instead by BalancingPool
  • #30  ActorRef router2 = Akka.system().actorOf(new RoundRobinPool(5).props(Props.create(AnActor.class)),"router2"); for (int i = 0; i < 10; i++) { router2.tell("i="+i, null); }
  • #31 val router = system.actorOf(Props[MyActor].withRouter(RoundRobinRouter (nrOfInstances = 5)) , name = "myRouterActor") 使用remote actor的例子, //創建remote actor的列表 val addresses = Seq( Address("akka", "remotesys", "host1", 1234),Address("akka", "remotesys", "host2", 1234)) val routerRemote = system.actorOf(Props[MyEchoActor].withRouter(RemoteRouterConfig(RoundRobinRouter(5), addresses)))
  • #37 Fire and forget:這是一個單向的消息發送模式,異步發送消息後,立即返回,消息的生產者不需要消息消費者的任何響應信息,Actor通過tell()方法來實現。 Send and receive:這種模式下,消息的生產者希望得到消息消費者的應答信息,並且等待接收應答消息。消息依然是異步發送,返回future,代表一個潛在的應該信息,這個和Java語言的Future語義是一致的。Actor使用ask()方法來實現這種模式。
  • #38 Null,ActorRef.noSender() 可用在A不是一個Actor時候
  • #41 Null,ActorRef.noSender() 可用在A不是一個Actor時候
  • #44 If A extented UntypedActor
  • #45 UntypedActorContext
  • #48 http://doc.akka.io/docs/akka/snapshot/java/fault-tolerance.html
  • #62 http://doc.akka.io/docs/akka/2.3.9/java/remoting.html http://www.gtan.com/akka_doc/scala/remoting.html