1 akka - jug ru grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfakka.routing По...

102
1 Akka.NET

Upload: others

Post on 14-Sep-2020

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

1

Akka.NET

Page 2: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

2

1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 20160

500

1000

1500

2000

2500

3000

3500

4000

0

10

20

30

40

50

60

70

1 1 1 1 1 1 1 1 1 2 24 4

8 8

16 16

32 32

64

200300

400500

1000

1800

2530

3200

3600

2200

29303000

32003330 3330

3150 3200 3150 3150 3150

Тактовая частота и количество ядер по годам

Частота (МГц) Ядра

Page 3: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

3

Page 4: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

4

Многопоточность

Ожидания

Реальность

Page 5: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

5

Page 6: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

6

Вертикальное масштабирование

Page 7: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

7

Вертикальное масштабирование

Горизонтальное масштабирование

Page 8: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

8

Вертикальное масштабирование

Горизонтальное масштабирование Эластичность

Page 9: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

9

Вертикальное масштабирование

Горизонтальное масштабирование Эластичность

Parallel LinqTPL – async/await

Потоки

Page 10: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

10

Вертикальное масштабирование

Горизонтальное масштабирование Эластичность

Parallel LinqTPL – async/await

Потоки

WCFWeb API

ServiceStackMSMQ

Page 11: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

11

Вертикальное масштабирование

Горизонтальное масштабирование Эластичность

Parallel LinqTPL – async/await

Потоки

WCFWeb API

ServiceStackMSMQ

Page 12: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

12

Что такое Актор?

Page 13: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

13

Это — единица организации программного кода

Что такое Актор?

Page 14: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

14

Это — единица организации программного кода

Что такое Актор?

ООП

ПоведениеСостояние

Синхронные* вызовы

Акторы

ПоведениеСостояние

Асинхронные сообщения

Page 15: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

15

Это — единица организации программного кода

Что такое Актор?

ООП

ПоведениеСостояние

Синхронные* вызовы

Акторы

ПоведениеСостояние

Асинхронные сообщения

Не нужно думать о:

- разделяемом состоянии- видимости состояния

- потоках, блокировках, конкурентных коллекциях, и т. п.

Page 16: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

16

Каковы накладные расходы

● 2.5 миллиона акторов на гигабайт памяти● 50 миллионов сообщений в секунду на локальной машине● Дешевле, чем потоки

Page 17: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

17

Th

read

Pool Actor

1Actor

1Actor

1Actor

1Actor

2Actor

2

Actor2Actor2 Actor3

Actor3

Actor4

Actor4 Actor4Actor4

Actor1Actor1

Actor3Actor3 Actor4Actor4

Actor2Actor2

Actor1Actor1

Actor3Actor3

Actor2Actor2

Time

● Акторы работают в пуле потоков, нет расходов на переключения контекста.

● Есть возможность управлять тем, где и как будет выполняться актор.2.5 миллиона акторов на гигабайт памяти

Page 18: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

18

Актор можно использовать как...

● поток● экземпляр объекта/компонента● колбек/подписчик● синглетон или сервис (например, слой работы с бд)● маршрутизатор, балансировщик, пул● сервис вне текущего процесса● конечный автомат

Page 19: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

19

Модель акторов используют:

● Erlang● Facebook WhatsApp (Erlang)● RabbitMQ (Erlang)● CouchDB (Erlang)● LinkedIn.com (JVM Akka)● Walmart.com (JVM Akka)● Blizzard (JVM Akka)

Page 20: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

20

Анатомия актора

ActorRefActorRefActorRefActorRef

АкторАктор

СостояниеСостояние

НадзорНадзор

Дочерние акторы

Дочерние акторы

Почтовый ящик

ПоведениеПоведение

Транспорт

Page 21: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

21

Действия с акторами

1) Define

2) Create

3) Send

4) Become

5) Supervise

Page 22: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

22

public class GreetingActor : ReceiveActor

{

public class Greet

{

public string Who { get; private set; }

public Greet(string who)

{

Who = who;

}

}

public GreetingActor()

{

Receive<Greet>(greet => Console.WriteLine(greet.Who));

}

}

Page 23: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

23

var system = ActorSystem.Create("my-system");var actorRef = system.ActorOf<GreetingActor>("my-actor");actorRef.Tell(new GreetingActor.Greet("World"));

Page 24: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

24

var system = ActorSystem.Create("my-system");var actorRef = system.ActorOf(Props.Create<GreetingActor>() .WithRouter(new RoundRobinPool(10)), "my-actor");actorRef.Tell(new GreetingActor.Greet("World"));

Page 25: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

25

var system = ActorSystem.Create("my-system");var actorRef = system.ActorOf(Props.Create<GreetingActor>() .WithDeploy(new Deploy(new RemoteScope( Address.Parse("akka.tcp://[email protected]:6001")))), "my-actor");

actorRef.Tell(new GreetingActor.Greet("World"));

Page 26: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

26

user

/

sys

Page 27: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

27

a1

user

/

sys

Page 28: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

28a2 a3

a1

user

/

sys

Page 29: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

29

a4 a5

a2 a3

a1

user

/

sys

Page 30: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

30

a4 a5

a2 a3

a1

user

/

sys

Page 31: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

31

a4 a5

a2 a3

a1

user

/

sys

Page 32: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

32

a4 a5

a2 a3

a1

user

/

sys

/user/a1/a2/a5

Page 33: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

33

Обработка исключений в C, C#, Java...

Page 34: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

34

Page 35: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

35

Page 36: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

36

Error Kernel

Page 37: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

37

/

Page 38: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

38

/

Page 39: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

39

/

Page 40: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

40

/

Page 41: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

41

/

Page 42: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

42

/

Page 43: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

43

/

Page 44: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

44

/

Page 45: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

45

/

Page 46: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

46

/

Page 47: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

47

/

Page 48: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

48

/

Page 49: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

49

/

Page 50: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

50

/

Page 51: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

51

Другой компьютер/процесс

Page 52: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

52

protected override SupervisorStrategy SupervisorStrategy()

{

return new OneForOneStrategy(5, new TimeSpan(0, 1, 0), e =>

e is ArithmeticException ? Directive.Resume

: e is IOException ? Directive.Restart

: Directive.Escalate);

}

Page 53: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

53

class CallCentreOperator{ public enum States { Offline, Idle, InCall, Busy } private States _state; public void DoSomethingUseful() { if(_state==States.Offline) ... else if(_state == States.Idle) ... ... }}

Page 54: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

54

public class CallCentreOperator : ReceiveActor{ private readonly ActorSelection _callInitiator; private readonly ActorSelection _callRouter; private string OperatorContactNumber => string.Format("client:{0}", Self.Path.Name);

public CallCentreOperator() { _callInitiator = Context.ActorSelection("/user/twiliocallinitiator"); _callRouter = Context.ActorSelection("/user/callrouter"); Become(Offline); }

public void Offline() { Receive<AgentConnected>(m => { Become(Idle); }); }...

}

Page 55: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

55

public class CallCentreOperator : ReceiveActor{ private readonly ActorSelection _callInitiator; private readonly ActorSelection _callRouter; private string OperatorContactNumber => string.Format("client:{0}", Self.Path.Name);

public CallCentreOperator() { _callInitiator = Context.ActorSelection("/user/twiliocallinitiator"); _callRouter = Context.ActorSelection("/user/callrouter"); Become(Offline); }

public void Offline() { Receive<AgentConnected>(m => { Become(Idle); }); }...

}

Page 56: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

56

public class CallCentreOperator : ReceiveActor{ private readonly ActorSelection _callInitiator; private readonly ActorSelection _callRouter; private string OperatorContactNumber => string.Format("client:{0}", Self.Path.Name);

public CallCentreOperator() { _callInitiator = Context.ActorSelection("/user/twiliocallinitiator"); _callRouter = Context.ActorSelection("/user/callrouter"); Become(Offline); }

public void Offline() { Receive<AgentConnected>(m => { Become(Idle); }); }...

}

Page 57: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

57

public void Idle() { Receive<AgentDisconnected>(m => { Become(Offline); }); Receive<IncomingCallMessage>(m => { string url = String.Format("/twilio/client_connected?conference={0}", m.ConferenceId); _callInitiator.Tell(new CreateCall(OperatorContactNumber, url)); _callRouter.Tell(new OperatorUnavailable()); Become(InCall); }); } public void InCall() { Receive<AgentDisconnected>(m => { Become(Offline); }); Receive<CallCompleteMessage>(m => { Become(Wrapup); Context.System.Scheduler.ScheduleTellOnce(TimeSpan.FromSeconds(10.0), Self, new OperatorReadyUp(), Sender); }); }

Page 58: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

58

Akka.Routing

По контролю времени жизни:- Pool- Group

По логике маршрутизации● RandomRouter● SmallestMailboxRouter● BroadcastRouter● RoundRobinRouter● ConsistentHashRouter● ScatterGatherFirstCompletedRouter● TailChoppingRouter

Page 59: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

59

RoundRobinRouter

12

1

2

3

34

4

Router

Routee1

Routee2

Routee3

Page 60: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

60

BroadcastRouter

12

12

12

12

Router Routee2

Routee3

Routee1Шлёт всемШлёт всем

Page 61: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

61

ConsistentHashRouter

ZY

Z

Y

X

AX

A

Router

Routee1

Routee2

Routee3

Одинаковый «индекс хэша»Одинаковый «индекс хэша»

«индекс хэша» привязан к актору«индекс хэша» привязан к актору

Page 62: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

62

Routee1

Routee2

Routee3

?

?

?

?

Sender !

Шлём всем, получаем первый ответ, отправляем запрашивающему(Task.WaitAny)

Шлём всем, получаем первый ответ, отправляем запрашивающему(Task.WaitAny)

ScatterGatherFirstCompletedRouter

Router

Page 63: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

63

Routee1

Routee2

Routee3

Sender

TailChoppingRouter

Router

Page 64: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

64

Routee1

Routee2

Routee3

?Sender

TailChoppingRouter

Router

Page 65: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

65

Routee1

Routee2

Routee3

?

?

Sender

TailChoppingRouter

Router

Page 66: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

66

Routee1

Routee2

Routee3

?

?

Sender

TailChoppingRouter

Router

Routee1

Page 67: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

67

Routee1

Routee2

Routee3

?

?

Sender

TailChoppingRouter

Router ?

Routee1

Page 68: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

68

Routee1

Routee2

Routee3

?

?

Sender

TailChoppingRouter

Router ?

Routee1

Routee2

Page 69: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

69

Routee1

Routee2

Routee3

?

?

Sender

TailChoppingRouter

Router ?

Routee1

Routee2 !

Page 70: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

70

Routee1

Routee2

Routee3

?

?

Sender !

TailChoppingRouter

Router ?

Routee1

Routee2 !

Page 71: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

71

Routee1

Routee2

Routee3

?

?

Sender !

Шлёт случайному, если не получает ответа, шлёт следующему

Шлёт случайному, если не получает ответа, шлёт следующему

TailChoppingRouter

Router ?

Routee1

Routee2 !

Page 72: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

72

Akka.Cluster

Seed Node

Page 73: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

73

Akka.Cluster

Node

Seed Node

Page 74: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

74

Akka.Cluster

Node

Seed Node

Page 75: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

75

Akka.Cluster

Node

Seed Node

Node

Page 76: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

76

Akka.Cluster

Node

Seed Node

Node

Page 77: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

77

Akka.Cluster

Node

Seed Node

Node

Page 78: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

78

Akka.Cluster

Node

Seed Node

Node

Node

Page 79: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

79

Akka.Cluster

Node

Seed Node

Node

Node

Page 80: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

80

Akka.Cluster

Node

Seed Node

Node

Node

Page 81: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

81

Akka.Cluster

Node

Seed Node

Node

Node

Page 82: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

82

Akka.Cluster

Node

Seed Node

Node

Node

Page 83: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

83

Akka.Cluster

Node

Seed Node

Node

Node

Node

Page 84: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

84

Akka.Persistence

Page 85: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

85

События

Запросы

Команды

CQRS(Command/Query Request Separation)

Потребитель(UI, слой API, etc)

Доменная модельМодель для чтения

База для чтенияБаза для записи

и работы доменной модели

Page 86: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

86

public class Bus{

public List<Passenger> Passengers { get; set; }public Bus(){

Passengers = new List<Passenger>();}public void Update(PassengerAddedEvent ev){

Passengers.Add(ev.Passenger);}

}

Page 87: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

87

public class PassengerAddedEvent{

public PassengerAddedEvent(Passenger passenger){

Passenger = passenger;}public Passenger Passenger { get; private set; }

}

Page 88: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

88

public class AddPassengerCommand{

public AddPassengerCommand(Passenger passenger){

Passenger = passenger;}public Passenger Passenger { get; private set; }

}

public class AddPassengerCommandResult{

public bool Added { get; set; }public AddPassengerCommandResult(bool added){

Added = added;}

}

Page 89: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

89

public class BusActor : PersistentActor

{

Bus _state = new Bus();

protected override bool ReceiveRecover(object message) { ... }

protected override bool ReceiveCommand(object message) { ... }

public override string PersistenceId { get };

public BusActor(int id)

{

PersistenceId = id;

}

public static Props Props(int id) => Props.Create<BusActor>(id);

}

Page 90: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

90

protected override bool ReceiveCommand(object message){

var addPassenger = message as AddPassengerCommand;if (addPassenger != null){

if (_state.Passengers.Count > 10 || addPassenger.Passenger.Drunk)Sender.Tell(new AddPassengerCommandResult(false));

else{

Persist(new PassengerAddedEvent(addPassenger.Passenger), e =>{

_state.Update(e));Sender.Tell(new AddPassengerCommandResult(true));

}}

}else if (message as string == "print")

Console.WriteLine(string.Join(", ", _state.Passengers.Select(p => p.Name)));else if (message as string == "snap")

SaveSnapshot(_state);else return false;return true;

}

Page 91: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

91

protected override bool ReceiveCommand(object message){

var addPassenger = message as AddPassengerCommand;if (addPassenger != null){

if (_state.Passengers.Count > 10 || addPassenger.Passenger.Drunk)Sender.Tell(new AddPassengerCommandResult(false));

else{

Persist(new PassengerAddedEvent(addPassenger.Passenger), e =>{

_state.Update(e));Sender.Tell(new AddPassengerCommandResult(true));

}}

}else if (message as string == "print")

Console.WriteLine(string.Join(", ", _state.Passengers.Select(p => p.Name)));else if (message as string == "snap")

SaveSnapshot(_state);else return false;return true;

}

Page 92: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

92

protected override bool ReceiveCommand(object message){

var addPassenger = message as AddPassengerCommand;if (addPassenger != null){

if (_state.Passengers.Count > 10 || addPassenger.Passenger.Drunk)Sender.Tell(new AddPassengerCommandResult(false));

else{

Persist(new PassengerAddedEvent(addPassenger.Passenger), e =>{

_state.Update(e));Sender.Tell(new AddPassengerCommandResult(true));

}}

}else if (message as string == "print")

Console.WriteLine(string.Join(", ", _state.Passengers.Select(p => p.Name)));else if (message as string == "snap")

SaveSnapshot(_state);else return false;return true;

}

Page 93: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

93

protected override bool ReceiveCommand(object message){

var addPassenger = message as AddPassengerCommand;if (addPassenger != null){

if (_state.Passengers.Count > 10 || addPassenger.Passenger.Drunk)Sender.Tell(new AddPassengerCommandResult(false));

else{

Persist(new PassengerAddedEvent(addPassenger.Passenger), e =>{

_state.Update(e));Sender.Tell(new AddPassengerCommandResult(true));

}}

}else if (message as string == "print")

Console.WriteLine(string.Join(", ", _state.Passengers.Select(p => p.Name)));else if (message as string == "snap")

SaveSnapshot(_state);else return false;return true;

}

Page 94: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

94

protected override bool ReceiveRecover(object message){

Bus offeredState;

if (message is SnapshotOffer && (offeredState = ((SnapshotOffer)message).Snapshot as Bus) != null)

_state = offeredState;

else if (message is PassengerAddedEvent)

_state.Update(message as PassengerAddedEvent);

else return false;

return true;

}

Page 95: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

95

protected override bool ReceiveRecover(object message){

Bus offeredState;

if (message is SnapshotOffer && (offeredState = ((SnapshotOffer)message).Snapshot as Bus) != null)

_state = offeredState;

else if (message is PassengerAddedEvent)

_state.Update(message as PassengerAddedEvent);

else return false;

return true;

}

Page 96: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

96

protected override bool ReceiveRecover(object message){

Bus offeredState;

if (message is SnapshotOffer && (offeredState = ((SnapshotOffer)message).Snapshot as Bus) != null)

_state = offeredState;

else if (message is PassengerAddedEvent)

_state.Update(message as PassengerAddedEvent);

else return false;

return true;

}

Page 97: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

97

public class BusViewActor : PersistentView

{

private readonly string _name;

private int _cnt;

public BusViewActor(string persistenceId, string name)

{

PersistenceId = persistenceId;

_name = name;

}

...

}

Page 98: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

98

protected override bool Receive(object message){ var passengerAdded = message as PassengerAddedEvent; var query = message as GetCountQuery; if (passengerAdded != null) { if (passengerAdded.Passenger.Name == _name) _cnt++; } else if (query != null) Sender.Tell(new GetCountQueryResult(_cnt)); ...}

Page 99: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

99

protected override bool Receive(object message){ var passengerAdded = message as PassengerAddedEvent; var query = message as GetCountQuery; if (passengerAdded != null) { if (passengerAdded.Passenger.Name == _name) _cnt++; } else if (query != null) Sender.Tell(new GetCountQueryResult(_cnt)); ...}

Page 100: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

100

protected override bool Receive(object message){ var passengerAdded = message as PassengerAddedEvent; var query = message as GetCountQuery; if (passengerAdded != null) { if (passengerAdded.Passenger.Name == _name) _cnt++; } else if (query != null) Sender.Tell(new GetCountQueryResult(_cnt)); ...}

Page 101: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

101

Cluster Event Sourcing Demo

https://github.com/kekekeks/dotnext-akka-demo/

Page 102: 1 Akka - JUG Ru Grouppublic.jugru.org/dotnext/2015/piter/tsukanov.pdfAkka.Routing По контролю времени жизни: - Pool - Group По логике маршрутизации

102

Akka.NET

http://getakka.net/

https://github.com/akkadotnet/akka.net/

https://gitter.im/akkadotnet/akka.net