Slide 1

Slide 1 text

Akka (Actor) in Practice Sunghyun Hwang !1

Slide 2

Slide 2 text

Software Engineer @Rainist We are making Banksalad !2

Slide 3

Slide 3 text

!3

Slide 4

Slide 4 text

!4

Slide 5

Slide 5 text

Akka !5

Slide 6

Slide 6 text

Akka is the implementation of the Actor Model on the JVM [1] !6

Slide 7

Slide 7 text

Actor Model !7

Slide 8

Slide 8 text

!8 class Pizza { private var slices = 8 def eat(nrOfSlices: Int = 1): Int = { if (slices >= nrOfSlices) { slices = slices - nrOfSlices return nrOfSlices } else { throw OutOfPizzaException } } }

Slide 9

Slide 9 text

!9 class Pizza { private var slices = 8 def eat(nrOfSlices: Int = 1): Int = { if (slices >= nrOfSlices) { slices = slices - nrOfSlices return nrOfSlices } else { throw OutOfPizzaException } } }

Slide 10

Slide 10 text

!10 Pizza Person("A") Person("B")

Slide 11

Slide 11 text

!11 Pizza Person("A") Person("B") .eat(6)

Slide 12

Slide 12 text

!12 Pizza Person("A") Person("B") .eat(6)

Slide 13

Slide 13 text

!13 Pizza Person("A") Person("B") .eat(6) .eat(3)

Slide 14

Slide 14 text

!14 Pizza Person("A") Person("B") .eat(6) .eat(3) OOP

Slide 15

Slide 15 text

!15 Pizza Person("A") Person("B") .eat(6) .eat(3) OOP Pizza Person("A") Person("B") T1 T2

Slide 16

Slide 16 text

!16 Pizza Person("A") Person("B") .eat(6) .eat(3) OOP Pizza Person("A") Person("B") .eat(6) .eat(3) T1 T2

Slide 17

Slide 17 text

!17 Pizza Person("A") Person("B") .eat(6) .eat(3) OOP Pizza Person("A") Person("B") .eat(6) .eat(3) T1 T2

Slide 18

Slide 18 text

!18 # ❓

Slide 19

Slide 19 text

!19 .eat(6) .eat(3) Unfortunately, the encapsulation model of objects does not guarantee anything about what happens in that section.

Slide 20

Slide 20 text

!20 Unfortunately, the encapsulation model of objects does not guarantee anything about what happens in that section. (…) Now, imagine this issue compounded by the existence of many threads. [2] .eat(6) .eat(3) .eat(2) .eat(8)

Slide 21

Slide 21 text

An actor is a container for State, Behavior, a Mailbox, Child Actors and a Supervisor Strategy. All of this is encapsulated behind an Actor Reference. [3] !21

Slide 22

Slide 22 text

!22 PizzaActor

Slide 23

Slide 23 text

!23 PizzaActor

Slide 24

Slide 24 text

!24 PizzaActor

Slide 25

Slide 25 text

!25 PizzaActor % &

Slide 26

Slide 26 text

!26 PizzaActor '( % &

Slide 27

Slide 27 text

!27 PizzaActor '( % &

Slide 28

Slide 28 text

!28 PizzaActor '( % & ✉

Slide 29

Slide 29 text

!29 PizzaActor '( % &

Slide 30

Slide 30 text

!30 PizzaActor '( % &

Slide 31

Slide 31 text

!31 PizzaActor '( % &

Slide 32

Slide 32 text

!32 PizzaActor '( % &

Slide 33

Slide 33 text

!33 PizzaActor '( % &

Slide 34

Slide 34 text

!34 PizzaActor '( % & 0

Slide 35

Slide 35 text

!35 PizzaActor '( % & 0 ⚡

Slide 36

Slide 36 text

!36 PizzaActor '( % &

Slide 37

Slide 37 text

OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. — Alan Kay [4] !37

Slide 38

Slide 38 text

The actor model adopts the philosophy that everything is an actor. [5] !38

Slide 39

Slide 39 text

What Akka is For !39

Slide 40

Slide 40 text

The Actor model alone, while great for many use cases, do not solve all concurrency and scalability problems. !40

Slide 41

Slide 41 text

The Actor model alone, while great for many use cases, do not solve all concurrency and scalability problems. (…) In addition to STM, Akka provides several other concurrency abstractions such as Agents and Dataflow Concurrency. [6] !41

Slide 42

Slide 42 text

Akka is a toolkit for building highly concurrent, distributed, and resilient message-driven applications for Java and Scala [1] !42

Slide 43

Slide 43 text

• Actor (Mostly) • I/O • Cluster • Cluster Tools • Persistence • Streams • Alpakka • HTTP • Typed !43 Akka

Slide 44

Slide 44 text

3 Months with Akka !44

Slide 45

Slide 45 text

!45 Recommending Actor

Slide 46

Slide 46 text

!46 Recommending Actor Maximizing Actor Maximizing Actor

Slide 47

Slide 47 text

!47 Recommending Actor Maximizing Actor Maximizing Actor Computing Actor Computing Actor Computing Actor Computing Actor Computing Actor Computing Actor

Slide 48

Slide 48 text

!48 Recommending Actor Maximizing Actor Maximizing Actor Computing Actor Computing Actor Computing Actor Computing Actor Computing Actor Computing Actor

Slide 49

Slide 49 text

!49 Recommending Actor Maximizing Actor Maximizing Actor

Slide 50

Slide 50 text

Akka is a tool, not a framework. !50

Slide 51

Slide 51 text

Akka is a tool, not a framework. !51 trade-off

Slide 52

Slide 52 text

!52 override def receive: Receive = { case WannaEatPizza(nr) ⇒ eat(nr) case DoNotWannaEatPiazza ⇒ ??? }

Slide 53

Slide 53 text

!53 override def receive: Receive = { case WannaEatPizza(nr) ⇒ eat(nr) case DoNotWannaEatPiazza ⇒ ??? } type Receive = PartialFunction[Any, Unit]

Slide 54

Slide 54 text

override def receive: Receive = { case WannaEatPizza(nr) ⇒ eat(nr) case OrderPizza(addr) ⇒ procOrder(addr) case CancelOrder(num) ⇒ cancel(num) case ShowPizzaMenu ⇒ sender ! pizzas case DoNotWannaEatPiazza ⇒ sender ! SoWhat }

Slide 55

Slide 55 text

Single Responsibility Principle !55

Slide 56

Slide 56 text

“A class should have only one reason to change.” — Robert C. Martin [7] !56

Slide 57

Slide 57 text

!57 class CounterActor extends Actor { var cnt: Int = 0 override def receive = { case Tick ⇒ cnt = cnt + 1 sender ! cnt } }

Slide 58

Slide 58 text

!58 def ticker(cnt: Int): Receive = { case Tick ⇒ context become ticker(cnt + 1) }

Slide 59

Slide 59 text

One actor is no Actor !59

Slide 60

Slide 60 text

Actor → Concurrency !60

Slide 61

Slide 61 text

Concurrency → Actor !61

Slide 62

Slide 62 text

!62 class SomeActor extends Actor { override def receive = { case id: Int ⇒ val card = database.query(s"SELECT * FROM card WHERE id = $id") val cached = cache.get(card.slug) sender ! cached } }

Slide 63

Slide 63 text

!63 Future { val card = database.query(s"SELECT * FROM card WHERE id = $id") cache.get(card.slug) }

Slide 64

Slide 64 text

!64 val a1 = actor ? 1 val a2 = actor ? 2 for { r1 ← a1 r2 ← a2 } yield (r1, r2) val f1 = fut(1) val f2 = fut(2) for { r1 ← f1 r2 ← f2 } yield (r1, r2)

Slide 65

Slide 65 text

Future is Composable, Actor is not. !65

Slide 66

Slide 66 text

class StreamActor extends Actor { override def receive = { case Data(x, y, z) ⇒ other ! convert(x, y, z) } } !66

Slide 67

Slide 67 text

• Monix.Observable • FS2 • RxJava/RxScala !67

Slide 68

Slide 68 text

!68 1 2 3

Slide 69

Slide 69 text

!69 1 2 3 unidirectional

Slide 70

Slide 70 text

!70 1 2 3 unidirectional 1 2 3 10 20 30

Slide 71

Slide 71 text

!71 1 2 3 unidirectional 1 2 3 10 20 30 bidirectional

Slide 72

Slide 72 text

!72 “To a man with a hammer, everything looks like a nail.” — Mark Twain

Slide 73

Slide 73 text

We are hiring! https://rainist.com/recruit/engineer • Back-end Engineer • Data Engineer • Data Scientist • Android Engineer • iOS Engineer • QA Engineer • Security Engineer • … X Engineer !73

Slide 74

Slide 74 text

Q&A !74

Slide 75

Slide 75 text

Materials !75 • [Akka Official Documents](https://akka.io) • [The Zen of Akka - by Konrad Malawski](https://www.youtube.com/ watch?v=vgFoKOxrTzg) • [The best is yet to come - State of Akka in 2017 by Konrad Malawski] (https://www.youtube.com/watch?v=CGyIPVGB2-4) • [Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors](https://www.slideshare.net/jboner/akka-simpler- scalability-faulttolerance-concurrency-remoting-through-actors/)

Slide 76

Slide 76 text

!76 • [1] https://akka.io • [2] https://doc.akka.io/docs/akka/current/guide/actors-motivation.html#the- challenge-of-encapsulation • [3] https://doc.akka.io/docs/akka/2.5/general/actors.html#what-is-an-actor- • [4] http://www.purl.org/stefan_ram/pub/doc_kay_oop_en • [5] https://en.wikipedia.org/wiki/Actor_model#Fundamental_concepts • [6] https://www.lightbend.com/blog/why-akka • [7] (2003, Martin, Robert C.) References