52
akka.net

Reactive Programming in .Net - actorbased computing with Akka.Net

Embed Size (px)

Citation preview

Page 1: Reactive Programming in .Net - actorbased computing with Akka.Net

akka.net

Page 3: Reactive Programming in .Net - actorbased computing with Akka.Net

Reactive Manifest und Akka.Net

Page 4: Reactive Programming in .Net - actorbased computing with Akka.Net

Wie kommen wir da hin? Reactive Manifesto

Page 5: Reactive Programming in .Net - actorbased computing with Akka.Net

event Handling data flow graph processing

System Architecure

zuverlässige skalierbare

elastic

message-driven

resilient

responsive

http://www.reactivemanifesto.org/de

Page 6: Reactive Programming in .Net - actorbased computing with Akka.Net

Elasticreact to load

Message-DrivenServices / Components Interaction

Resilientreact to failures

Responsivereact to users

Reactive System

goal

methods

concepts

Page 7: Reactive Programming in .Net - actorbased computing with Akka.Net

resilient elastic

Page 8: Reactive Programming in .Net - actorbased computing with Akka.Net
Page 9: Reactive Programming in .Net - actorbased computing with Akka.Net

Up OutDown In

Page 10: Reactive Programming in .Net - actorbased computing with Akka.Net
Page 11: Reactive Programming in .Net - actorbased computing with Akka.Net

at first, dry theory…

Page 12: Reactive Programming in .Net - actorbased computing with Akka.Net
Page 13: Reactive Programming in .Net - actorbased computing with Akka.Net

Carl Hewitt (1973),Actor Model of Computation:Scalable Robust Information Systems

Page 14: Reactive Programming in .Net - actorbased computing with Akka.Net
Page 15: Reactive Programming in .Net - actorbased computing with Akka.Net
Page 16: Reactive Programming in .Net - actorbased computing with Akka.Net
Page 17: Reactive Programming in .Net - actorbased computing with Akka.Net

…jetzt.

Page 18: Reactive Programming in .Net - actorbased computing with Akka.Net

• Typesafe: Actor-Framework• Scala (JVM) => Java

• ausgereiftes, erprobtes Framework

• Akka.Net• Portierung von Akka (2013)

• Aaron Stannard Roger Johansson

• http://getakka.net

akka.net

Page 19: Reactive Programming in .Net - actorbased computing with Akka.Net

Concurreny

Scalability

Fault-tolerance

Simpler

Programming Model

Managed Runtime

Open Source Distribution

…with a single unified

Page 20: Reactive Programming in .Net - actorbased computing with Akka.Net

Scale UP

Scale OUT

Page 21: Reactive Programming in .Net - actorbased computing with Akka.Net
Page 22: Reactive Programming in .Net - actorbased computing with Akka.Net
Page 23: Reactive Programming in .Net - actorbased computing with Akka.Net
Page 24: Reactive Programming in .Net - actorbased computing with Akka.Net

http://doc.akka.io/docs/akka/current/intro/use-cases.html

Page 25: Reactive Programming in .Net - actorbased computing with Akka.Net

PM> Install-Package Akkanuget

using Akka.Actor;

using (var actorSystem = ActorSystem.Create("MyActorSystem")){

// universe}

nur innerhalb dieses Blocks„leben“ Aktoren

var actorSystem = ActorSystem.Create("MyActorSystem"));

// universe

actorSystem.WhenTerminated.Wait(); // wait for termination-taskactorSystem.AwaitTermination(); // deprecated

oder

Page 26: Reactive Programming in .Net - actorbased computing with Akka.Net

// universeIActorRef myActor = actorSystem.ActorOf(

Props.Create(() => new MyActor()));

using (var actorSystem = ActorSystem.Create("MyActorSystem")){

}

// talk to the actormyActor.Tell(new SomeMessage("rise up slave..."));

erzeuge AktorSystem

fordere spezifischenAktor an

sprich mit dem erhaltenenAktor

Page 27: Reactive Programming in .Net - actorbased computing with Akka.Net

public class SomeMessage{

public SomeMessage(string name){

Name = name;}

public string Name { get; private set; }}

public class MyActor : ReceiveActor{

public MyActor(){

Receive<string>(message => {Sender.Tell(message);

});

Receive<SomeMessage>(message => {// react to message

});}

}

alle Nachrichten sindimmutable

Nachrichten werdenprinzipiell nach ihremTyp unterschieden *

* es geht fein-granularerund abstrakter

Page 28: Reactive Programming in .Net - actorbased computing with Akka.Net

Receive<string>(s => Console.WriteLine("Received string: " + s)); //1Receive<int>(i => Console.WriteLine("Received integer: " + i)); //2

IActorRef sender = Sender;

Page 29: Reactive Programming in .Net - actorbased computing with Akka.Net

//Receive using FuncsReceive<string>(s =>{

if (s.Length > 5) {Console.WriteLine("1: " + s);return true;

}return false;

});Receive<string>(s => Console.WriteLine("2: " + s));

//predicatesReceive<string>(s => s.Length > 5, s => Console.WriteLine("1: " + s)); //1Receive<string>(s => s.Length > 2, s => Console.WriteLine("2: " + s)); //2Receive<string>(s => Console.WriteLine("3: " + s));

//handler priorityReceive<string>(s => s.Length > 5, s => Console.WriteLine("1: " + s)); //1Receive<string>(s => s.Length > 2, s => Console.WriteLine("2: " + s)); //2Receive<string>(s => Console.WriteLine("3: " + s)); //3

Page 30: Reactive Programming in .Net - actorbased computing with Akka.Net
Page 31: Reactive Programming in .Net - actorbased computing with Akka.Net

public class MyActor : ActorBase{

public MyActor(){

//nothing todo}

protected override bool Receive(object _message){

//handle different messagesvar message = _message as SomeMessage;if(message != null){

return false;}

return false;}

}

Nachrichten werdenprinzipiell nach ihremTyp unterschieden *

* es geht fein-granularerund abstrakter

Page 32: Reactive Programming in .Net - actorbased computing with Akka.Net

using Akka.Actor;

public class MyUntypedActor : UntypedActor{

protected override void OnReceive(object message) {

var msg = message as Messages.InputError; if (msg != null) {

// cool, its for me} else{

Unhandled(message); //from ActorBase}

} }

• anders als beim ReceiveActor müssen nicht behandelteNachrichten selbst als solche markiert werden

Page 33: Reactive Programming in .Net - actorbased computing with Akka.Net

IActorRef friend = Context.ActorOf(Props.Create(() => new MyReceiveActor()));sender.Tell(new SomeMessage("Re: " + message.Name));

IActorRef friend = ...friend.Tell(new SomeMessage("Forward: " + message.Name), sender);

IActorRef friend = ...friend.Forward(new SomeMessage("Forward: " + message.Name)); forward

tell + explicit sender

tell

Page 34: Reactive Programming in .Net - actorbased computing with Akka.Net

Nicht die da, andere….

Page 35: Reactive Programming in .Net - actorbased computing with Akka.Net

event-driven thread

Actor

Behavior

Mailbox

State

Childs

Supervisor-Strategy

ActorRef 1 2 34Transport [Akka]

IActorRef myActor = ...myActor.Tell(new Message("four"));

• IActorRef: handle oder reference auf einen Actor• Nachrichten werden niemals direkt an einen

Actor gesendet• ActorSystem fügt Metadaten (Sender, Empfänger) hinzu• ActorSystem garantiert Ankunft jeder Nachricht *

Page 36: Reactive Programming in .Net - actorbased computing with Akka.Net

IActorRef

• Actor Namen sind optional• best practise: named actors

Create

Look up

IActorRef myActor = actorSystem.ActorOf(Props.Create(() => new MyActor()),"myactor1"

);

• adressierbar über ActorPath• Actoren bilden eine Hierarchy

Parent

Children

Sender

ActorSelection randomActor =actorSystem.ActorSelection("akka://ActorSys/user/myactor1");

Page 37: Reactive Programming in .Net - actorbased computing with Akka.Net

Props props1 = Props.Create(typeof(MyActor));

Props props2 = Props.Create(() => new MyActor());

Props props3 = Props.Create<MyActor>();

typeof Syntax

lambda Syntax

generic Syntax

• einziger Weg um Parameterzu übergeben

• unsicher

Context.ActorOf(props2);

actorSystem.ActorOf(props2);

aus einem Actor heraus:

direkt im ActorSystem:-> erzeugt HierarchieVerwendung

Page 38: Reactive Programming in .Net - actorbased computing with Akka.Net
Page 39: Reactive Programming in .Net - actorbased computing with Akka.Net

akka.tcp://MySystem@localhost:9001/user/actorName1

Protocol

ActorSystem

Akka

Path

Akka Remote

Address

Page 40: Reactive Programming in .Net - actorbased computing with Akka.Net

/system

Guardians

/a1 /a2top levelactor

/b1

/c1 /cx

/b2

/c2 /cx

akka://ActorSystem/user

akka://ActorSystem/user/a1

akka://ActorSystem/user/a1/b2

akka://ActorSystem/user/a1/*/cx

/user

/

Page 41: Reactive Programming in .Net - actorbased computing with Akka.Net
Page 42: Reactive Programming in .Net - actorbased computing with Akka.Net

parent

parent

Failure

SupervisionStrategy• Restart, Stop, Resume, Escalate

• 2 Default-Strategien: One-For-One und All-For-One

Page 43: Reactive Programming in .Net - actorbased computing with Akka.Net

• erklärtes Ziel ist es Fehler einzugrenzen:

• localizing the failure: fehleranfälligen Code

The critical thing to know here is that *whatever action is

taken on a parent propagates to its children*. If a parent is

halted, all its children halt. If it is restarted, all its children

restart.

Page 44: Reactive Programming in .Net - actorbased computing with Akka.Net

protected override SupervisorStrategy SupervisorStrategy() {// immer die gleiche Entscheidungreturn new OneForOneStrategy(

maxNrOfRetries: 10,withinTimeRange: TimeSpan.FromSeconds(30),localOnlyDecider: exception =>{

Console.WriteLine("*** Supervision: Restart");return Directive.Restart;

});

}

Page 45: Reactive Programming in .Net - actorbased computing with Akka.Net

Clients[SignalR]

Clients[SignalR]

Clients[SignalR]

GameHub[SignalR]

Bridge-Actor

[Akka]

GameCtrl-Actor

[Akka]

Player-Actor

[Akka]

internetjoin

attack attack

refreshState

sendState

changeHealth

join

attack

Page 46: Reactive Programming in .Net - actorbased computing with Akka.Net

Clients[SignalR]

Clients[SignalR]

Clients[SignalR]

GameHub[SignalR]

internet

join

attack

Act

orS

yste

m[A

kka]

Page 47: Reactive Programming in .Net - actorbased computing with Akka.Net

public class MvcApplication : HttpApplication {

protected void Application_Start(){

//ASP.Net Stuff: Filters, Routes, ...

//Akka initGameActorSystem.Create();

}

void Application_End(){

GameActorSystem.Shutdown();}

}

Page 48: Reactive Programming in .Net - actorbased computing with Akka.Net

public static class GameActorSystem{

private static ActorSystem ActorSystem;private static IGameEventsPusher _gameEventsPusher;

public static void Create(){

_gameEventsPusher = new SignalRGameEventPusher();

ActorSystem = Akka.Actor.ActorSystem.Create("GameSystem");

ActorReferences.GameController = ActorSystem.ActorOf<GameControllerActor>();ActorReferences.SignalRBridge = ActorSystem.ActorOf(

Props.Create(() =>new SignalRBridgeActor(_gameEventsPusher, ActorReferences.GameController)),

"SignalRBridge„);

}

public static void Shutdown(){

ActorSystem.Shutdown();ActorSystem.AwaitTermination(TimeSpan.FromSeconds(1));

}

public static class ActorReferences ...}

Page 49: Reactive Programming in .Net - actorbased computing with Akka.Net

class SignalRGameEventPusher : IGameEventsPusher {

private static readonly IHubContext _gameHubContext;

static SignalRGameEventPusher() //static CTOR{

_gameHubContext = GlobalHost.ConnectionManager.GetHubContext<GameHub>();}

public void PlayerJoined(string playerName, int playerHealth){

_gameHubContext.Clients.All.playerJoined(playerName, playerHealth);}

public void UpdatePlayerHealth(string playerName, int playerHealth){

_gameHubContext.Clients.All.updatePlayerHealth(playerName, playerHealth);}

}

GameHub[SignalR]

Act

orS

yste

m[A

kka]

playerJoined

updatePlayerHealth

ClientsClients

Clients

Page 50: Reactive Programming in .Net - actorbased computing with Akka.Net

public class GameHub : Hub{

public void JoinGame(string playerName){

GameActorSystem.ActorReferences.SignalRBridge.Tell(new JoinGameMessage(playerName));

}

public void Attack(string playerName){

GameActorSystem.ActorReferences.SignalRBridge.Tell(new AttackPlayerMessage(playerName));

}}

GameHub[SignalR]

join

attack

Act

orS

yste

m[A

kka]

Page 51: Reactive Programming in .Net - actorbased computing with Akka.Net
Page 52: Reactive Programming in .Net - actorbased computing with Akka.Net

Closed

Open

Deleted

open close

delete