SlideShare a Scribd company logo
Networks & Types
Johan Andrén, Akka Team
Devoxx UK, London, 2018-05-11
The Future of Akka
Johan Andrén
Akka Team
Stockholm Scala User Group
@apnylle
markatta.com/codemonkey/
johan.andren@lightbend.com
Build powerful reactive, concurrent,
and distributed applications more easily
Akka
• Distributed programming made simple
• High performance messaging (up to 1 million msgs/s over network on Artery,
close to 40-50 million msgs/s locally)

• Asynchronous and Reactive by default
• Initiator of Reactive Streams initiative, now part of JDK9
• Productive development, with tuned type-safe tools
What does Akka solve?
What are the tools?
Actors – simple & high performance concurrency
Cluster, Cluster tools – tools for building distributed systems
Streams – reactive streams implementation
Persistence – CQRS + Event Sourcing for Actors
HTTP – fully async streaming HTTP Server
Alpakka – Reactive Streams Integrations a’la Camel
Complete Java & Scala APIs for all features
Actors – simple & high performance concurrency
Cluster, Cluster tools – tools for building distributed systems
Streams – reactive streams implementation
Persistence – CQRS + Event Sourcing for Actors
HTTP – fully async streaming HTTP Server
Alpakka – Reactive Streams Integrations a’la Camel
Complete Java & Scala APIs for all features.
All modules ready for preview, final polish during Q2 2018
Typed
Typed
Typed
(already type-safe)
(already type-safe)
(already type-safe)
What is coming soon?
Actor
Message
Inbox
MessageMessage
actorRef ! message
Akka Actor fundamentals
• mutate state (including spawning a child actor)
• send messages to other actors
• change its behavior
Actor
Message
Inbox
MessageMessage
An Actor can…
Local
ActorSystem
Message
Message
Actor
Actor
Actor
JVM 2
JVM 1
Distributed
ActorSystem
ActorSystem
Message
Message
Actor
Actor
Actor
class MyActor extends Actor {
def receive: Any => Unit = {
case Msg(a) =>
sender() ! “Hi there!”
}
}
Reminder of Akka “Classic” Actors
• Discoverability, how are things related
• More compile time type-safety, less runtime debugging
Types helps productivity! (and results in more reliable systems
in production)
The need for strong/strict typing
“Sending the wrong message to an actor is
actually quite uncommon”
– Myself, earlier this week
• Not a trivial problem: Topic of multiple research papers
to bring type-safety to the Actor model

•“TAkka” 2014, Phillip Wadler et al, University of Edinburgh
•“Reactors, Channels and Event Streams …” 2015, 

Aleksandar Prokopec, Martin Odersky, EPFL
•Typed Actors [RIP]
The need for strong/strict typing
Typed Actors
Burglar Alarm
• enabled/disabled with a pin code
• accepts notifications about “activity”
• if enabled on activity, sound the alarm
Example
DIY
// message protocol
trait AlarmMessage
case class EnableAlarm(pinCode: String) extends AlarmMessage
case class DisableAlarm(pinCode: String) extends AlarmMessage
case object ActivityEvent extends AlarmMessage
// behavior
def enabled(pinCode: String): Behavior[AlarmMessage] =
Behaviors.receive[AlarmMessage] { (ctx, msg) =>
msg match {
case DisableAlarm(enteredCode) if enteredCode == pinCode =>
ctx.log.info("Disabling alarm")
disabled(pinCode) // change behavior
case ActivityEvent =>
ctx.log.warning("OEOEOEOEOEOE alarm, activity detected!")
Behaviors.same
case _ =>
Behaviors.ignore
}
}
def disabled(pinCode: String): Behavior[AlarmMessage] =
Behaviors.receive[AlarmMessage] {
case EnableAlarm(enteredCode) if enteredCode == pinCode =>
enabled(pinCode) // change behavior
case _ =>
Behaviors.ignore
}
// behavior
def enabled(pinCode: String): Behavior[AlarmMessage] =
Behaviors.receive[AlarmMessage] { (ctx, msg) =>
msg match {
case DisableAlarm(enteredCode) if enteredCode == pinCode =>
ctx.log.info("Disabling alarm")
disabled(pinCode) // change behavior
case ActivityEvent =>
ctx.log.warning("OEOEOEOEOEOE alarm, activity detected!")
Behaviors.same
case _ =>
Behaviors.ignore
}
}
def disabled(pinCode: String): Behavior[AlarmMessage] =
Behaviors.receive[AlarmMessage] {
case EnableAlarm(enteredCode) if enteredCode == pinCode =>
enabled(pinCode) // change behavior
case _ =>
Behaviors.ignore
}
// behavior
def enabled(pinCode: String): Behavior[AlarmMessage] =
Behaviors.receive[AlarmMessage] { (ctx, msg) =>
msg match {
case DisableAlarm(enteredCode) if enteredCode == pinCode =>
ctx.log.info("Disabling alarm")
disabled(pinCode) // change behavior
case ActivityEvent =>
ctx.log.warning("OEOEOEOEOEOE alarm, activity detected!")
Behaviors.same
case _ =>
Behaviors.ignore
}
}
def disabled(pinCode: String): Behavior[AlarmMessage] =
Behaviors.receive[AlarmMessage] {
case EnableAlarm(enteredCode) if enteredCode == pinCode =>
enabled(pinCode) // change behavior
case _ =>
Behaviors.ignore
}
// running it
val system = ActorSystem(enabled("0000"), "AlarmSystem")
// system is also reference to top level actor
val alarmRef: ActorRef[AlarmMessage] = system
alarmRef ! DisableAlarm("1234")
alarmRef ! ActivityEvent
alarmRef ! DisableAlarm("0000")
alarmRef ! ActivityEvent
alarmRef ! EnableAlarm("0000")
// running it
val system = ActorSystem(enabled("0000"), "AlarmSystem")
// system is also reference to top level actor
val alarmRef: ActorRef[AlarmMessage] = system
alarmRef ! DisableAlarm("1234")
alarmRef ! ActivityEvent
alarmRef ! DisableAlarm("0000")
alarmRef ! ActivityEvent
alarmRef ! EnableAlarm(“0000")
alarmRef ! ”0000” // compile error
Compile-time safety
Untyped Actors
Untyped Actors vs Akka Typed
Akka Typed Actors
• sender() propagated
automatically
• any message type can
be sent to any Actor
• actor returns nothing
upon processing a
message
• sender is optionally part
of the protocol
• only the right type of messages
can be sent:
ActorRef[MessageProtocol]
• behaviors always return the
next behavior
Akka Cluster + Akka Typed
ActorSystem ActorSystem
ActorSystem
Distributed Burglar Alarm
• we can have any number of
nodes
• a sensor on any node can
report activity to the alarm
Example, iteration 2
DYI
Distributed
Receptionist
Typed Receptionist
Receptionist
Receptionist
Register(Key[AlarmMessage],
ActorRef[AlarmMessage])
ActorRef[AlarmMessage]
ActorRef[SensorEvent]
Subscribe(key, actorRef)
val receptionist = Receptionist(system).ref
val alarmKey = ServiceKey[AlarmMessage]("alarm")
def startAlarm(pinCode: String): Behavior[AlarmMessage] =
Behaviors.setup { ctx =>
receptionist ! Register(alarmKey, ctx.self, ctx.system.deadLetters)
enabled(pinCode)
}
val receptionist = Receptionist(system).ref
val alarmKey = ServiceKey[AlarmMessage]("alarm")
def startAlarm(pinCode: String): Behavior[AlarmMessage] =
Behaviors.setup { ctx =>
receptionist ! Register(alarmKey, ctx.self, ctx.system.deadLetters)
enabled(pinCode)
}
// protocol
trait SensorEvent
case object WindowOpened extends SensorEvent
// behavior
def sensorBehavior: Behavior[SensorEvent] =
Behaviors.setup { ctx =>
var alarms = Set.empty[ActorRef[AlarmMessage]]
Receptionist(ctx.system).ref ! Receptionist.Subscribe(
alarmKey, ctx.self.narrow[Listing[AlarmMessage]])
Behaviors.receive[Any]((ctx, msg) =>
msg match {
case Listing(_, updatedAlarms: Set[ActorRef[AlarmMessage]]) =>
// updated list of alarms known
alarms = updatedAlarms
Behaviors.same
case WindowOpened =>
// inform all known alarms about activity
alarms.foreach(_ ! ActivityEvent)
// protocol
trait SensorEvent
case object WindowOpened extends SensorEvent
// behavior
def sensorBehavior: Behavior[SensorEvent] =
Behaviors.setup { ctx =>
var alarms = Set.empty[ActorRef[AlarmMessage]]
Receptionist(ctx.system).ref ! Receptionist.Subscribe(
alarmKey, ctx.self.narrow[Listing[AlarmMessage]])
Behaviors.receive[Any]((ctx, msg) =>
msg match {
case Listing(_, updatedAlarms: Set[ActorRef[AlarmMessage]]) =>
// updated list of alarms known
alarms = updatedAlarms
Behaviors.same
case WindowOpened =>
// inform all known alarms about activity
alarms.foreach(_ ! ActivityEvent)
def sensorBehavior: Behavior[SensorEvent] =
Behaviors.setup { ctx =>
var alarms = Set.empty[ActorRef[AlarmMessage]]
Receptionist(ctx.system).ref ! Receptionist.Subscribe(
alarmKey, ctx.self.narrow[Listing[AlarmMessage]])
Behaviors.receive[Any]((ctx, msg) =>
msg match {
case Listing(_, updatedAlarms: Set[ActorRef[AlarmMessage]]) =>
// updated list of alarms known
alarms = updatedAlarms
Behaviors.same
case WindowOpened =>
// inform all known alarms about activity
alarms.foreach(_ ! ActivityEvent)
Behaviors.same
}
)
}.narrow // narrow Behavior[Any] down to Behavior[SensorEvent]
// running it
val system1 = ActorSystem(startAlarm("0000"), "AlarmSystem")
val system2 = ActorSystem(sensorBehavior, "AlarmSystem")
// programmatic cluster formation
val node1 = Cluster(system1)
val node2 = Cluster(system2)
// node1 joins itself to form cluster
node1.manager ! Join(node1.selfMember.address)
// node2 joins the now existing cluster
node2.manager ! Join(node1.selfMember.address)
// a bit later the burglar comes
after(1.day) {
system2 ! WindowOpened
}
Akka Streams over
Network
🚚🚚
🚚
🚚
🚚
Akka Stream fundamentals
SinkSource Flow
Elements
Akka Stream fundamentals
SinkSource Flow
potential
asynchronous
boundary
potential
asynchronous
boundary
Akka Stream fundamentals
SinkSource Flow
1 msg/s
buffer size 3
10 msg/s
💥 💥
💥 🔥
Akka Stream fundamentals
SinkSource Flow
1 msg/s
buffer size 3
10 msg/s
hand me 2 morehand me 2 more
1 msg/s
JVM 2
ActorSystem
JVM 1
ActorSystem
(special)
SinkSource Flow
Flow Sink
SourceRef
StreamRefs — new feature since Akka 2.5.10
JVM 2
ActorSystem
JVM 1
ActorSystem
(special)
SinkSource Flow
Flow SinkSourceRef
This end controls
the pace through
backpressure
StreamRefs — new feature since Akka 2.5.10
SourceRef sending side
Scala
class SendingActor extends Actor {
import context.dispatcher
implicit val mat = ActorMaterializer()(context)
val numbersSource = Source(1 to 100000)
def receive = {
case SendMeNumbers ⇒
val ref: Future[SourceRef[Int]] =
numbersSource.runWith(StreamRefs.sourceRef())
val reply: Future[SendMeNumbersReply] =
ref.map(ref => SendMeNumbersReply(ref))
reply pipeTo sender()
}
}
SourceRef receiving side
Scala
class ReceivingActor(sendingActor: ActorRef) extends Actor {
sendingActor ! SendMeNumbers
override def receive: Receive = {
case SendMeNumbersReply(sourceRef) =>
sourceRef.runWith(Sink.foreach(println))
}
}
StreamRefs — new feature since Akka 2.5.10
By design NOT a“distributed automatic stream
processing deployment and management framework”.
(e.g. how Spark, Flink or Beam could be described).
Ideal for
combining Alpakka Enterprise Integration
Data Processing or Ingestion Pipelines between ActorSystems
Docs:
doc.akka.io/docs/akka/2.5/typed/index.html
doc.akka.io/docs/akka/2.5/stream/stream-refs.html
More resources:
blog.akka.io
discuss.akka.io
developer.lightbend.com
www.lightbend.com/resources
Further reading…
http://akka.io
@apnylle
johan.andren@lightbend.com
Thanks for listening!

More Related Content

PDF
Next generation message driven systems with Akka
PDF
Next generation actors with Akka
PDF
Next generation message driven systems with Akka
PDF
Buiilding reactive distributed systems with Akka
PDF
Reactive stream processing using Akka streams
PDF
Reactive streams processing using Akka Streams
PDF
Reactive Applications in Java
PDF
Streaming all the things with akka streams
Next generation message driven systems with Akka
Next generation actors with Akka
Next generation message driven systems with Akka
Buiilding reactive distributed systems with Akka
Reactive stream processing using Akka streams
Reactive streams processing using Akka Streams
Reactive Applications in Java
Streaming all the things with akka streams

What's hot (20)

PPTX
Akka Actor presentation
PDF
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
PDF
Building reactive distributed systems with Akka
PDF
Akka streams - Umeå java usergroup
PDF
Akka lsug skills matter
PDF
Akka Cluster in Java - JCConf 2015
PDF
Actor Model Akka Framework
PDF
Sane Sharding with Akka Cluster
PPTX
Developing distributed applications with Akka and Akka Cluster
PPTX
Fullstack Conference - Proxies before proxies: The hidden gems of Javascript...
PDF
Async - react, don't wait - PingConf
PDF
Concurrecny inf sharp
PPTX
Introduction to rx java for android
PDF
Reactive Streams / Akka Streams - GeeCON Prague 2014
PDF
Reactive integrations with Akka Streams
PPTX
Introduction to Akka - Atlanta Java Users Group
PDF
Akka persistence == event sourcing in 30 minutes
PDF
The dark side of Akka and the remedy
PPTX
Samuele Resca - REACTIVE PROGRAMMING, DAMN. IT IS NOT ABOUT REACTJS - Codemot...
PDF
Back to the futures, actors and pipes: using Akka for large-scale data migration
Akka Actor presentation
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Building reactive distributed systems with Akka
Akka streams - Umeå java usergroup
Akka lsug skills matter
Akka Cluster in Java - JCConf 2015
Actor Model Akka Framework
Sane Sharding with Akka Cluster
Developing distributed applications with Akka and Akka Cluster
Fullstack Conference - Proxies before proxies: The hidden gems of Javascript...
Async - react, don't wait - PingConf
Concurrecny inf sharp
Introduction to rx java for android
Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive integrations with Akka Streams
Introduction to Akka - Atlanta Java Users Group
Akka persistence == event sourcing in 30 minutes
The dark side of Akka and the remedy
Samuele Resca - REACTIVE PROGRAMMING, DAMN. IT IS NOT ABOUT REACTJS - Codemot...
Back to the futures, actors and pipes: using Akka for large-scale data migration
Ad

Similar to Networks and types - the future of Akka (20)

PDF
Akka Typed (quick talk) - JFokus 2018
PDF
Building Reactive Applications with Akka & Java 8 - Bonèr
PDF
Introducing Akka
PDF
Networks and Types - the Future of Akka @ ScalaDays NYC 2018
PDF
Actor, an elegant model for concurrent and distributed computation
PPTX
Concurrency in Scala - the Akka way
ODP
Meetup slides
PDF
Scalaz 8 vs Akka Actors
PDF
Akka Typed — between Session Types and the Actor Model
PDF
Introduction to Actor Model and Akka
PDF
Building Stateful Microservices With Akka
PPTX
The dark side of Akka and the remedy - bp.scala meetup
PDF
Akka with Scala
PDF
Building Reactive Systems with Akka (in Java 8 or Scala)
PDF
PDF
Reactive applications and Akka intro used in the Madrid Scala Meetup
PDF
Akka (1)
PDF
A gentle introduction into AKKA and the actor model
PPTX
Nairobi JVM meetup : Introduction to akka
 
PDF
Message-based communication patterns in distributed Akka applications
Akka Typed (quick talk) - JFokus 2018
Building Reactive Applications with Akka & Java 8 - Bonèr
Introducing Akka
Networks and Types - the Future of Akka @ ScalaDays NYC 2018
Actor, an elegant model for concurrent and distributed computation
Concurrency in Scala - the Akka way
Meetup slides
Scalaz 8 vs Akka Actors
Akka Typed — between Session Types and the Actor Model
Introduction to Actor Model and Akka
Building Stateful Microservices With Akka
The dark side of Akka and the remedy - bp.scala meetup
Akka with Scala
Building Reactive Systems with Akka (in Java 8 or Scala)
Reactive applications and Akka intro used in the Madrid Scala Meetup
Akka (1)
A gentle introduction into AKKA and the actor model
Nairobi JVM meetup : Introduction to akka
 
Message-based communication patterns in distributed Akka applications
Ad

More from Johan Andrén (11)

PDF
Asynchronous stream processing with Akka Streams
PDF
Scala usergroup stockholm - reactive integrations with akka streams
PDF
VJUG24 - Reactive Integrations with Akka Streams
PDF
Introduction to akka actors with java 8
PDF
Scala frukostseminarium
PDF
Introduction to Akka
PDF
Async – react, don't wait
PDF
Akka frukostseminarium
PDF
Macros and reflection in scala 2.10
PDF
Introduction to Scala
PDF
Duchess scala-2012
Asynchronous stream processing with Akka Streams
Scala usergroup stockholm - reactive integrations with akka streams
VJUG24 - Reactive Integrations with Akka Streams
Introduction to akka actors with java 8
Scala frukostseminarium
Introduction to Akka
Async – react, don't wait
Akka frukostseminarium
Macros and reflection in scala 2.10
Introduction to Scala
Duchess scala-2012

Recently uploaded (20)

PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PPTX
Cloud computing and distributed systems.
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Machine learning based COVID-19 study performance prediction
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Approach and Philosophy of On baking technology
PPT
Teaching material agriculture food technology
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Encapsulation theory and applications.pdf
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Cloud computing and distributed systems.
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
20250228 LYD VKU AI Blended-Learning.pptx
Machine learning based COVID-19 study performance prediction
Diabetes mellitus diagnosis method based random forest with bat algorithm
Encapsulation_ Review paper, used for researhc scholars
Approach and Philosophy of On baking technology
Teaching material agriculture food technology
Spectral efficient network and resource selection model in 5G networks
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Agricultural_Statistics_at_a_Glance_2022_0.pdf
NewMind AI Weekly Chronicles - August'25 Week I
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Per capita expenditure prediction using model stacking based on satellite ima...
Dropbox Q2 2025 Financial Results & Investor Presentation
Encapsulation theory and applications.pdf
Review of recent advances in non-invasive hemoglobin estimation
The Rise and Fall of 3GPP – Time for a Sabbatical?

Networks and types - the future of Akka

  • 1. Networks & Types Johan Andrén, Akka Team Devoxx UK, London, 2018-05-11 The Future of Akka
  • 2. Johan Andrén Akka Team Stockholm Scala User Group @apnylle markatta.com/codemonkey/ johan.andren@lightbend.com
  • 3. Build powerful reactive, concurrent, and distributed applications more easily Akka
  • 4. • Distributed programming made simple • High performance messaging (up to 1 million msgs/s over network on Artery, close to 40-50 million msgs/s locally)
 • Asynchronous and Reactive by default • Initiator of Reactive Streams initiative, now part of JDK9 • Productive development, with tuned type-safe tools What does Akka solve?
  • 5. What are the tools? Actors – simple & high performance concurrency Cluster, Cluster tools – tools for building distributed systems Streams – reactive streams implementation Persistence – CQRS + Event Sourcing for Actors HTTP – fully async streaming HTTP Server Alpakka – Reactive Streams Integrations a’la Camel Complete Java & Scala APIs for all features
  • 6. Actors – simple & high performance concurrency Cluster, Cluster tools – tools for building distributed systems Streams – reactive streams implementation Persistence – CQRS + Event Sourcing for Actors HTTP – fully async streaming HTTP Server Alpakka – Reactive Streams Integrations a’la Camel Complete Java & Scala APIs for all features. All modules ready for preview, final polish during Q2 2018 Typed Typed Typed (already type-safe) (already type-safe) (already type-safe) What is coming soon?
  • 8. • mutate state (including spawning a child actor) • send messages to other actors • change its behavior Actor Message Inbox MessageMessage An Actor can…
  • 11. class MyActor extends Actor { def receive: Any => Unit = { case Msg(a) => sender() ! “Hi there!” } } Reminder of Akka “Classic” Actors
  • 12. • Discoverability, how are things related • More compile time type-safety, less runtime debugging Types helps productivity! (and results in more reliable systems in production) The need for strong/strict typing “Sending the wrong message to an actor is actually quite uncommon” – Myself, earlier this week
  • 13. • Not a trivial problem: Topic of multiple research papers to bring type-safety to the Actor model
 •“TAkka” 2014, Phillip Wadler et al, University of Edinburgh •“Reactors, Channels and Event Streams …” 2015, 
 Aleksandar Prokopec, Martin Odersky, EPFL •Typed Actors [RIP] The need for strong/strict typing
  • 15. Burglar Alarm • enabled/disabled with a pin code • accepts notifications about “activity” • if enabled on activity, sound the alarm Example DIY
  • 16. // message protocol trait AlarmMessage case class EnableAlarm(pinCode: String) extends AlarmMessage case class DisableAlarm(pinCode: String) extends AlarmMessage case object ActivityEvent extends AlarmMessage
  • 17. // behavior def enabled(pinCode: String): Behavior[AlarmMessage] = Behaviors.receive[AlarmMessage] { (ctx, msg) => msg match { case DisableAlarm(enteredCode) if enteredCode == pinCode => ctx.log.info("Disabling alarm") disabled(pinCode) // change behavior case ActivityEvent => ctx.log.warning("OEOEOEOEOEOE alarm, activity detected!") Behaviors.same case _ => Behaviors.ignore } } def disabled(pinCode: String): Behavior[AlarmMessage] = Behaviors.receive[AlarmMessage] { case EnableAlarm(enteredCode) if enteredCode == pinCode => enabled(pinCode) // change behavior case _ => Behaviors.ignore }
  • 18. // behavior def enabled(pinCode: String): Behavior[AlarmMessage] = Behaviors.receive[AlarmMessage] { (ctx, msg) => msg match { case DisableAlarm(enteredCode) if enteredCode == pinCode => ctx.log.info("Disabling alarm") disabled(pinCode) // change behavior case ActivityEvent => ctx.log.warning("OEOEOEOEOEOE alarm, activity detected!") Behaviors.same case _ => Behaviors.ignore } } def disabled(pinCode: String): Behavior[AlarmMessage] = Behaviors.receive[AlarmMessage] { case EnableAlarm(enteredCode) if enteredCode == pinCode => enabled(pinCode) // change behavior case _ => Behaviors.ignore }
  • 19. // behavior def enabled(pinCode: String): Behavior[AlarmMessage] = Behaviors.receive[AlarmMessage] { (ctx, msg) => msg match { case DisableAlarm(enteredCode) if enteredCode == pinCode => ctx.log.info("Disabling alarm") disabled(pinCode) // change behavior case ActivityEvent => ctx.log.warning("OEOEOEOEOEOE alarm, activity detected!") Behaviors.same case _ => Behaviors.ignore } } def disabled(pinCode: String): Behavior[AlarmMessage] = Behaviors.receive[AlarmMessage] { case EnableAlarm(enteredCode) if enteredCode == pinCode => enabled(pinCode) // change behavior case _ => Behaviors.ignore }
  • 20. // running it val system = ActorSystem(enabled("0000"), "AlarmSystem") // system is also reference to top level actor val alarmRef: ActorRef[AlarmMessage] = system alarmRef ! DisableAlarm("1234") alarmRef ! ActivityEvent alarmRef ! DisableAlarm("0000") alarmRef ! ActivityEvent alarmRef ! EnableAlarm("0000")
  • 21. // running it val system = ActorSystem(enabled("0000"), "AlarmSystem") // system is also reference to top level actor val alarmRef: ActorRef[AlarmMessage] = system alarmRef ! DisableAlarm("1234") alarmRef ! ActivityEvent alarmRef ! DisableAlarm("0000") alarmRef ! ActivityEvent alarmRef ! EnableAlarm(“0000") alarmRef ! ”0000” // compile error Compile-time safety
  • 22. Untyped Actors Untyped Actors vs Akka Typed Akka Typed Actors • sender() propagated automatically • any message type can be sent to any Actor • actor returns nothing upon processing a message • sender is optionally part of the protocol • only the right type of messages can be sent: ActorRef[MessageProtocol] • behaviors always return the next behavior
  • 23. Akka Cluster + Akka Typed ActorSystem ActorSystem ActorSystem
  • 24. Distributed Burglar Alarm • we can have any number of nodes • a sensor on any node can report activity to the alarm Example, iteration 2 DYI Distributed
  • 26. val receptionist = Receptionist(system).ref val alarmKey = ServiceKey[AlarmMessage]("alarm") def startAlarm(pinCode: String): Behavior[AlarmMessage] = Behaviors.setup { ctx => receptionist ! Register(alarmKey, ctx.self, ctx.system.deadLetters) enabled(pinCode) }
  • 27. val receptionist = Receptionist(system).ref val alarmKey = ServiceKey[AlarmMessage]("alarm") def startAlarm(pinCode: String): Behavior[AlarmMessage] = Behaviors.setup { ctx => receptionist ! Register(alarmKey, ctx.self, ctx.system.deadLetters) enabled(pinCode) }
  • 28. // protocol trait SensorEvent case object WindowOpened extends SensorEvent // behavior def sensorBehavior: Behavior[SensorEvent] = Behaviors.setup { ctx => var alarms = Set.empty[ActorRef[AlarmMessage]] Receptionist(ctx.system).ref ! Receptionist.Subscribe( alarmKey, ctx.self.narrow[Listing[AlarmMessage]]) Behaviors.receive[Any]((ctx, msg) => msg match { case Listing(_, updatedAlarms: Set[ActorRef[AlarmMessage]]) => // updated list of alarms known alarms = updatedAlarms Behaviors.same case WindowOpened => // inform all known alarms about activity alarms.foreach(_ ! ActivityEvent)
  • 29. // protocol trait SensorEvent case object WindowOpened extends SensorEvent // behavior def sensorBehavior: Behavior[SensorEvent] = Behaviors.setup { ctx => var alarms = Set.empty[ActorRef[AlarmMessage]] Receptionist(ctx.system).ref ! Receptionist.Subscribe( alarmKey, ctx.self.narrow[Listing[AlarmMessage]]) Behaviors.receive[Any]((ctx, msg) => msg match { case Listing(_, updatedAlarms: Set[ActorRef[AlarmMessage]]) => // updated list of alarms known alarms = updatedAlarms Behaviors.same case WindowOpened => // inform all known alarms about activity alarms.foreach(_ ! ActivityEvent)
  • 30. def sensorBehavior: Behavior[SensorEvent] = Behaviors.setup { ctx => var alarms = Set.empty[ActorRef[AlarmMessage]] Receptionist(ctx.system).ref ! Receptionist.Subscribe( alarmKey, ctx.self.narrow[Listing[AlarmMessage]]) Behaviors.receive[Any]((ctx, msg) => msg match { case Listing(_, updatedAlarms: Set[ActorRef[AlarmMessage]]) => // updated list of alarms known alarms = updatedAlarms Behaviors.same case WindowOpened => // inform all known alarms about activity alarms.foreach(_ ! ActivityEvent) Behaviors.same } ) }.narrow // narrow Behavior[Any] down to Behavior[SensorEvent]
  • 31. // running it val system1 = ActorSystem(startAlarm("0000"), "AlarmSystem") val system2 = ActorSystem(sensorBehavior, "AlarmSystem") // programmatic cluster formation val node1 = Cluster(system1) val node2 = Cluster(system2) // node1 joins itself to form cluster node1.manager ! Join(node1.selfMember.address) // node2 joins the now existing cluster node2.manager ! Join(node1.selfMember.address) // a bit later the burglar comes after(1.day) { system2 ! WindowOpened }
  • 34. Akka Stream fundamentals SinkSource Flow potential asynchronous boundary potential asynchronous boundary
  • 35. Akka Stream fundamentals SinkSource Flow 1 msg/s buffer size 3 10 msg/s 💥 💥 💥 🔥
  • 36. Akka Stream fundamentals SinkSource Flow 1 msg/s buffer size 3 10 msg/s hand me 2 morehand me 2 more 1 msg/s
  • 37. JVM 2 ActorSystem JVM 1 ActorSystem (special) SinkSource Flow Flow Sink SourceRef StreamRefs — new feature since Akka 2.5.10
  • 38. JVM 2 ActorSystem JVM 1 ActorSystem (special) SinkSource Flow Flow SinkSourceRef This end controls the pace through backpressure StreamRefs — new feature since Akka 2.5.10
  • 39. SourceRef sending side Scala class SendingActor extends Actor { import context.dispatcher implicit val mat = ActorMaterializer()(context) val numbersSource = Source(1 to 100000) def receive = { case SendMeNumbers ⇒ val ref: Future[SourceRef[Int]] = numbersSource.runWith(StreamRefs.sourceRef()) val reply: Future[SendMeNumbersReply] = ref.map(ref => SendMeNumbersReply(ref)) reply pipeTo sender() } }
  • 40. SourceRef receiving side Scala class ReceivingActor(sendingActor: ActorRef) extends Actor { sendingActor ! SendMeNumbers override def receive: Receive = { case SendMeNumbersReply(sourceRef) => sourceRef.runWith(Sink.foreach(println)) } }
  • 41. StreamRefs — new feature since Akka 2.5.10 By design NOT a“distributed automatic stream processing deployment and management framework”. (e.g. how Spark, Flink or Beam could be described). Ideal for combining Alpakka Enterprise Integration Data Processing or Ingestion Pipelines between ActorSystems