SlideShare a Scribd company logo
1 of 35
Download to read offline
Akka with Scala
Oto Brglez, June 2021
Gentle introduction to tomorrows tech Today.
Oto Brglez
• Engineering manager && Software Architect @ GWI
• R&D Stuff => 🚀
to 🌕
• Consultant / Founder @ OPALAB => epic.blog
• @otobrglez
bit.ly/oto-brglez-cv
* FB.com/groups/developerji
Do you use this stuff?
Yes.
What kind of problem are you
solving?
GET. NEW. DATA!
Pollpass
• Market Research platform with focus on
superior experience
• Conversations not surveys
• Real-time && distributed
• 16+ languages, X countries…
• Sophisticated scripting, routing and logic
• Expression engine, ASTs, piping etc…
• Enterprise grade and integrated
Future?
Voice
Simpler Concurrent & Distributed
Systems
Actors and Streams let you build systems that scale up,
using the resources of a server more efficiently, and out,
using multiple servers.
Resilient by Design
Building on the principles of The Reactive Manifesto
Akka allows you to write systems that self-heal and stay
responsive in the face of failures.
High Performance
Up to 50 million msg/sec on a single machine. Small
memory footprint; ~2.5 million actors per GB of heap.
Elastic & Decentralized
Distributed systems without single points of failure. Load
balancing and adaptive routing across nodes. Event
Sourcing and CQRS with Cluster Sharding. Distributed
Data for eventual consistency using CRDTs.
Reactive Streaming Data
Asynchronous non-blocking stream processing with
backpressure. Fully async and streaming HTTP server
and client provides a great platform for building
microservices. Streaming integrations with Alpakka.
* How Actors Work?
Akka Actors
class PersonActor(firstName: String, lastName: String) extends Actor with ActorLogging {
override def receive: Receive = {
case "eat-ice-cream" =>
log.info(s"$firstName has started eating ice cream. ")
Thread.sleep(5.seconds.toMillis)
log.info(s"$firstName has eaten his ice cream. ")
}
}
object MainApp extends App {
val system = ActorSystem("first-system")
val kid1: ActorRef = system.actorOf(Props(classOf[PersonActor], "Rudi", "Brglez"), "rudi")
val kid2: ActorRef = system.actorOf(Props(classOf[PersonActor], "Tinkara", "Brglez"), "tinkara")
val me: ActorRef = system.actorOf(Props(classOf[PersonActor], "Oto", "Brglez"), "oto")
kid1 ! "eat-ice-cream"
kid1 ! "eat-ice-cream"
kid1 ! "eat-ice-cream"
kid2 ! "eat-ice-cream"
me ! "drink-beer"
}
Actor that
represents a
person 👉
“Main” 👉
}business logic
AS initialisation 👉
Spawning actors{
Sending messages{
More messages{
object Person {
trait PersonCommand
final case object EatIceCream extends PersonCommand
final case object FinishedEatingIceCream extends PersonCommand
def apply(firstName: String): Behavior[PersonCommand] = idle(firstName)
private def idle(firstName: String): Behavior[PersonCommand] =
Behaviors.receiveMessage[PersonCommand] {
case EatIceCream => eatingIceCream(firstName)
case _ => Behaviors.same
}
private def eatingIceCream(firstName: String): Behavior[PersonCommand] =
Behaviors.setup { context =>
Behaviors.withTimers[PersonCommand] { timers =>
context.log.info(s"$firstName has started eating his ice-cream. ")
timers.startSingleTimer(FinishedEatingIceCream, 3.seconds)
Behaviors.receiveMessage {
case FinishedEatingIceCream =>
context.log.info(s"$firstName is done with ice-cream. ")
idle(firstName)
case _ =>
context.log.info(s"$firstName: Sorry, I'm still eating,...")
Behaviors.same
}
}
}
}
“Idle state” 👉
“Eating state” 👉
Commands {
object Family {
sealed trait FamilyCommand
final case class AddPerson(firstName: String) extends FamilyCommand
final case class EatCake(firstName: String) extends FamilyCommand
def apply(): Behavior[FamilyCommand] = Behaviors.receive {
case (context, AddPerson(firstName)) =>
context.spawn(Person(firstName), firstName)
Behaviors.same
case (context, EatCake(firstName)) =>
context.child(firstName)
.map(_.asInstanceOf[ActorRef[Person.PersonCommand]])
.foreach(ref => ref ! Person.EatIceCream)
Behaviors.same
case _ => Behaviors.unhandled
}
}
Commands {
Child is created 👉
“EatIceCream” is sent to
child with given name 👉
object MainApp extends App {
val system = ActorSystem[Family.FamilyCommand](Family(), "family")
system ! Family.AddPerson("Rudi")
system ! Family.AddPerson("Tinkara")
system ! Family.AddPerson("Oto")
system ! Family.EatCake("Rudi")
system ! Family.EatCake("Tinkara")
system ! Family.EatCake("Rudi")
system ! Family.EatCake("Tinkara")
system ! "drink beer!"
}
👈 💥
Won’t actually compile since AkkaTyped required
proper types and Scala compiler won’t allow this “String”!
Akka Streams
The Weather
Temperature
Example ☀
💥 Network Problems
💥 500 Error
💥 Missing tag!
💥 Out of memory
💥 Recipient is br0ken
Network is still down!!! 💥
object MainApp extends LazyLogging {
def main(args: Array[String]): Unit = {
implicit val system: ActorSystem = ActorSystem("temperature-system")
import system.dispatcher
val changeDetector: ActorRef = system.actorOf(Props(classOf[ChangeDetector]), "change-detector")
Source.tick(1.seconds, 2.seconds, "Tick")
.mapAsync(1) { _ => getMeasurement }
.alsoTo(Sink.foreach(v => logger.info(s"Latest measurement is ${v.getOrElse("none")} ")))
.mapAsync(1)(measurement => changeDetector.ask(measurement)(1.second))
.collect { case change: ChangeDetector.Changed => change }
.runWith(Sink.foreach(change =>
logger.info(s"Temperature change from ${change.from} to ${change.to}, ${direction(change)}.")))
}
private def getMeasurement(implicit system: ActorSystem, ec: ExecutionContext): Future[Measurement] =
for {
response <- Http().singleRequest(HttpRequest(uri = ARSOLjubljanaURL))
nodes <- Unmarshal(response.entity).to[NodeSeq]
measurement = (nodes  "t").headOption.flatMap(_.text.toDoubleOption)
} yield measurement
private val direction: ChangeDetector.Changed => String = {
case ChangeDetector.Changed(from, to) if to > from => "up "
case ChangeDetector.Changed(from, to) if to < from => "down "
case _ => "impossible."
}
}
Every 2 seconds send “Tick” 👉
Execute request to Web Service 👉
In parallel write to output 👉
“Ask” actor to detect changes 👉
Only care about actual “changes” 👉
Run and see the changes 👉
This part is for issuing
request, dealing with
response and XML parsing
{
val getMeasurementsFlow: Flow[String, Measurement, NotUsed] =
RestartFlow.onFailuresWithBackoff(RestartSettings(10.seconds, 30.seconds, 0.3)) { () =>
Flow[String].mapAsyncUnordered(1) { _ => getMeasurement }
}
Source.tick(1.seconds, 2.seconds, "Tick")
.via(getMeasurementsFlow)
.alsoTo(Sink.foreach(v => logger.info(s"Latest measurement is ${v.getOrElse("none")} ")))
.mapAsync(1)(measurement => changeDetector.ask(measurement)(1.second))
.collect { case change: ChangeDetector.Changed => change }
.runWith(Sink.foreach(change =>
logger.info(s"The temperature has changed. From ${change.from} to ${change.to}, ${direction(change)}.")))
Pass “Tick” to Flow 👉
This Flow is
restarted if
failures occur 👉
Akka HTTP*
Alpakka
• Data transformation: Parsing lines, JSON Framing, Compression, CSV, Text transcoding,
encoding etc…
• AMQP, Apache Camel, Apache Cassandra, Apache Geode, Apache Kafka, Apache Kudu,
Apache Solr, Avro Parquet, AWS EventBridge, AWS DynamoDB, AWS Kinesis and
Firehose, AWS Lambda, AWS S3, AWS SNS, AWS SQS, Azure Event Hubs, Azure IoT Hub,
Azure Storage Queue, Couchbase, Elasticsearch, Eventuate, File, FS2, FTP, Google
Common, Google Cloud BigQuery, Google Cloud Pub/Sub, Google Cloud Pub/Sub
gRPC, Google Cloud Storage, Google FCM, gRPC, Hadoop Distributed File System -
HDFS, HBase, HTTP, IBM Bluemix Cloud Object Storage, IBM Db2 Event Store, InfluxDB,
IronMQ, JMS, MapR Database, MongoDB, MQTT, MQTT Streaming, OrientDB, Pulsar,
Pravega, Server-sent Events (SSE), Slick (JDBC), Spring Web, TCP, UDP, Unix Domain
Socket, … + more
Akka Persistance
class SurveyActor(id: UUID) extends PersistentActor with ActorLogging {
override def persistenceId: String = id.toString
var survey: Survey = Survey()
def updateState(event: Event): Unit = {
event match {
case NameSet(name) =>
survey = survey.copy(name = Some(name))
case TextNodeAppended(name) =>
survey = survey.copy(nodes = survey.nodes ++ List(Text(name)))
}
}
override def receiveRecover: Receive = {
case event: Event => updateState(event)
case SnapshotOffer(_, surveySnapshot: Survey) =>
survey = surveySnapshot
}
override def receiveCommand: Receive = {
case SetName(name) =>
persist(NameSet(name)) { event =>
updateState(event)
context.system.eventStream.publish(event)
}
case AppendTextNode(name) =>
persist(TextNodeAppended(name)) { event =>
updateState(event)
context.system.eventStream.publish(event)
}
case GetSurvey =>
sender() ! survey
}
}
sealed trait Command
sealed trait Event
case class SetName(name: String) extends Command
case class NameSet(name: String) extends Event
case class AppendTextNode(name: String) extends Command
case class TextNodeAppended(name: String) extends Event
case object GetSurvey extends Command
final case class Survey(
name: Option[String] = None,
nodes: List[Node] = List.empty[Node])
sealed trait Node
case class Text(name: String) extends Node
object MainApp extends App {
val system: ActorSystem = ActorSystem("surveys")
import system.dispatcher
val s1 = system.actorOf(Props(classOf[SurveyActor], UUID.randomUUID()))
s1 ! SetName("This is my first example")
s1 ! SetName("First Survey V1")
s1 ! AppendTextNode("Hello!")
s1 ! AppendTextNode("This is example of Akka Persistence.")
s1 ! SetName("Short name")
s1.ask(GetSurvey)(20.seconds).onComplete {
case Success(value: Survey) =>
println(value.asJson)
}
}
Execute commands
and persist events
👉
State from events
👉
Recovery and
snapshots
👉
Akka Cluster + Discovery
Please, give it a try!
@otobrglez
otobrglez@gmail.com
meetup.com/sugslo
scalaslovenia.slack.com

More Related Content

What's hot

2015 05 27 JSConf - concurrency and parallelism final
2015 05 27   JSConf - concurrency and parallelism final2015 05 27   JSConf - concurrency and parallelism final
2015 05 27 JSConf - concurrency and parallelism finalNaveed Ihsanullah
 
The Ring programming language version 1.9 book - Part 78 of 210
The Ring programming language version 1.9 book - Part 78 of 210The Ring programming language version 1.9 book - Part 78 of 210
The Ring programming language version 1.9 book - Part 78 of 210Mahmoud Samir Fayed
 
Scalding - Hadoop Word Count in LESS than 70 lines of code
Scalding - Hadoop Word Count in LESS than 70 lines of codeScalding - Hadoop Word Count in LESS than 70 lines of code
Scalding - Hadoop Word Count in LESS than 70 lines of codeKonrad Malawski
 
GreenDao Introduction
GreenDao IntroductionGreenDao Introduction
GreenDao IntroductionBooch Lin
 
Getting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETGetting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETTomas Jansson
 
Should I Use Scalding or Scoobi or Scrunch?
Should I Use Scalding or Scoobi or Scrunch? Should I Use Scalding or Scoobi or Scrunch?
Should I Use Scalding or Scoobi or Scrunch? DataWorks Summit
 
Introduction to Scalding and Monoids
Introduction to Scalding and MonoidsIntroduction to Scalding and Monoids
Introduction to Scalding and MonoidsHugo Gävert
 
Using Arbor/ RGraph JS libaries for Data Visualisation
Using Arbor/ RGraph JS libaries for Data VisualisationUsing Arbor/ RGraph JS libaries for Data Visualisation
Using Arbor/ RGraph JS libaries for Data VisualisationAlex Hardman
 
Writing Hadoop Jobs in Scala using Scalding
Writing Hadoop Jobs in Scala using ScaldingWriting Hadoop Jobs in Scala using Scalding
Writing Hadoop Jobs in Scala using ScaldingToni Cebrián
 
The Ring programming language version 1.10 book - Part 80 of 212
The Ring programming language version 1.10 book - Part 80 of 212The Ring programming language version 1.10 book - Part 80 of 212
The Ring programming language version 1.10 book - Part 80 of 212Mahmoud Samir Fayed
 
Simplifying Persistence for Java and MongoDB with Morphia
Simplifying Persistence for Java and MongoDB with MorphiaSimplifying Persistence for Java and MongoDB with Morphia
Simplifying Persistence for Java and MongoDB with MorphiaMongoDB
 
Mongodb debugging-performance-problems
Mongodb debugging-performance-problemsMongodb debugging-performance-problems
Mongodb debugging-performance-problemsMongoDB
 
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015NoSQLmatters
 
Hazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSHazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSuzquiano
 

What's hot (20)

2015 05 27 JSConf - concurrency and parallelism final
2015 05 27   JSConf - concurrency and parallelism final2015 05 27   JSConf - concurrency and parallelism final
2015 05 27 JSConf - concurrency and parallelism final
 
greenDAO
greenDAOgreenDAO
greenDAO
 
The Ring programming language version 1.9 book - Part 78 of 210
The Ring programming language version 1.9 book - Part 78 of 210The Ring programming language version 1.9 book - Part 78 of 210
The Ring programming language version 1.9 book - Part 78 of 210
 
Scalding - Hadoop Word Count in LESS than 70 lines of code
Scalding - Hadoop Word Count in LESS than 70 lines of codeScalding - Hadoop Word Count in LESS than 70 lines of code
Scalding - Hadoop Word Count in LESS than 70 lines of code
 
WOTC_Import
WOTC_ImportWOTC_Import
WOTC_Import
 
GreenDao Introduction
GreenDao IntroductionGreenDao Introduction
GreenDao Introduction
 
Getting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETGetting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NET
 
Should I Use Scalding or Scoobi or Scrunch?
Should I Use Scalding or Scoobi or Scrunch? Should I Use Scalding or Scoobi or Scrunch?
Should I Use Scalding or Scoobi or Scrunch?
 
Introduction to Scalding and Monoids
Introduction to Scalding and MonoidsIntroduction to Scalding and Monoids
Introduction to Scalding and Monoids
 
Using Arbor/ RGraph JS libaries for Data Visualisation
Using Arbor/ RGraph JS libaries for Data VisualisationUsing Arbor/ RGraph JS libaries for Data Visualisation
Using Arbor/ RGraph JS libaries for Data Visualisation
 
XTW_Import
XTW_ImportXTW_Import
XTW_Import
 
Presto in Treasure Data
Presto in Treasure DataPresto in Treasure Data
Presto in Treasure Data
 
Writing Hadoop Jobs in Scala using Scalding
Writing Hadoop Jobs in Scala using ScaldingWriting Hadoop Jobs in Scala using Scalding
Writing Hadoop Jobs in Scala using Scalding
 
Green dao
Green daoGreen dao
Green dao
 
The Ring programming language version 1.10 book - Part 80 of 212
The Ring programming language version 1.10 book - Part 80 of 212The Ring programming language version 1.10 book - Part 80 of 212
The Ring programming language version 1.10 book - Part 80 of 212
 
Functions
FunctionsFunctions
Functions
 
Simplifying Persistence for Java and MongoDB with Morphia
Simplifying Persistence for Java and MongoDB with MorphiaSimplifying Persistence for Java and MongoDB with Morphia
Simplifying Persistence for Java and MongoDB with Morphia
 
Mongodb debugging-performance-problems
Mongodb debugging-performance-problemsMongodb debugging-performance-problems
Mongodb debugging-performance-problems
 
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
 
Hazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSHazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMS
 

Similar to Akka with Scala

Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupHenrik Engström
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every dayVadym Khondar
 
Presto anatomy
Presto anatomyPresto anatomy
Presto anatomyDongmin Yu
 
Spark what's new what's coming
Spark what's new what's comingSpark what's new what's coming
Spark what's new what's comingDatabricks
 
From polling to real time: Scala, Akka, and Websockets from scratch
From polling to real time: Scala, Akka, and Websockets from scratchFrom polling to real time: Scala, Akka, and Websockets from scratch
From polling to real time: Scala, Akka, and Websockets from scratchSergi González Pérez
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
Bringing order to the chaos! - Paulo Lopes - Codemotion Amsterdam 2018
Bringing order to the chaos! - Paulo Lopes - Codemotion Amsterdam 2018Bringing order to the chaos! - Paulo Lopes - Codemotion Amsterdam 2018
Bringing order to the chaos! - Paulo Lopes - Codemotion Amsterdam 2018Codemotion
 
Java/Scala Lab: Борис Трофимов - Обжигающая Big Data.
Java/Scala Lab: Борис Трофимов - Обжигающая Big Data.Java/Scala Lab: Борис Трофимов - Обжигающая Big Data.
Java/Scala Lab: Борис Трофимов - Обжигающая Big Data.GeeksLab Odessa
 
Writing RESTful web services using Node.js
Writing RESTful web services using Node.jsWriting RESTful web services using Node.js
Writing RESTful web services using Node.jsFDConf
 
Machine Learning with Microsoft Azure
Machine Learning with Microsoft AzureMachine Learning with Microsoft Azure
Machine Learning with Microsoft AzureDmitry Petukhov
 
Node.js - async for the rest of us.
Node.js - async for the rest of us.Node.js - async for the rest of us.
Node.js - async for the rest of us.Mike Brevoort
 
5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)Christian Rokitta
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksMongoDB
 
Ajax tutorial
Ajax tutorialAjax tutorial
Ajax tutorialKat Roque
 
Leveraging Hadoop in your PostgreSQL Environment
Leveraging Hadoop in your PostgreSQL EnvironmentLeveraging Hadoop in your PostgreSQL Environment
Leveraging Hadoop in your PostgreSQL EnvironmentJim Mlodgenski
 
Comet with node.js and V8
Comet with node.js and V8Comet with node.js and V8
Comet with node.js and V8amix3k
 
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-MallaKerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-MallaSpark Summit
 
[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기NAVER D2
 

Similar to Akka with Scala (20)

Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetup
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
 
Presto anatomy
Presto anatomyPresto anatomy
Presto anatomy
 
Spark what's new what's coming
Spark what's new what's comingSpark what's new what's coming
Spark what's new what's coming
 
From polling to real time: Scala, Akka, and Websockets from scratch
From polling to real time: Scala, Akka, and Websockets from scratchFrom polling to real time: Scala, Akka, and Websockets from scratch
From polling to real time: Scala, Akka, and Websockets from scratch
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
Bringing order to the chaos! - Paulo Lopes - Codemotion Amsterdam 2018
Bringing order to the chaos! - Paulo Lopes - Codemotion Amsterdam 2018Bringing order to the chaos! - Paulo Lopes - Codemotion Amsterdam 2018
Bringing order to the chaos! - Paulo Lopes - Codemotion Amsterdam 2018
 
Java/Scala Lab: Борис Трофимов - Обжигающая Big Data.
Java/Scala Lab: Борис Трофимов - Обжигающая Big Data.Java/Scala Lab: Борис Трофимов - Обжигающая Big Data.
Java/Scala Lab: Борис Трофимов - Обжигающая Big Data.
 
Writing RESTful web services using Node.js
Writing RESTful web services using Node.jsWriting RESTful web services using Node.js
Writing RESTful web services using Node.js
 
Machine Learning with Microsoft Azure
Machine Learning with Microsoft AzureMachine Learning with Microsoft Azure
Machine Learning with Microsoft Azure
 
Node.js - async for the rest of us.
Node.js - async for the rest of us.Node.js - async for the rest of us.
Node.js - async for the rest of us.
 
5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)
 
huhu
huhuhuhu
huhu
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New Tricks
 
Ajax tutorial
Ajax tutorialAjax tutorial
Ajax tutorial
 
Leveraging Hadoop in your PostgreSQL Environment
Leveraging Hadoop in your PostgreSQL EnvironmentLeveraging Hadoop in your PostgreSQL Environment
Leveraging Hadoop in your PostgreSQL Environment
 
Comet with node.js and V8
Comet with node.js and V8Comet with node.js and V8
Comet with node.js and V8
 
Html5 For Jjugccc2009fall
Html5 For Jjugccc2009fallHtml5 For Jjugccc2009fall
Html5 For Jjugccc2009fall
 
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-MallaKerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
 
[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기
 

More from Oto Brglez

The Compression Puzzle Challenge
The Compression Puzzle ChallengeThe Compression Puzzle Challenge
The Compression Puzzle ChallengeOto Brglez
 
Becoming S/W Engineer
Becoming S/W EngineerBecoming S/W Engineer
Becoming S/W EngineerOto Brglez
 
How to over-engineer things and have fun? Building a modern, distributed real...
How to over-engineer things and have fun? Building a modern, distributed real...How to over-engineer things and have fun? Building a modern, distributed real...
How to over-engineer things and have fun? Building a modern, distributed real...Oto Brglez
 
Oto Brglez - Tips for better tests
Oto Brglez - Tips for better testsOto Brglez - Tips for better tests
Oto Brglez - Tips for better testsOto Brglez
 
Kdaj lahko uporabimo piškotke?
Kdaj lahko uporabimo piškotke?Kdaj lahko uporabimo piškotke?
Kdaj lahko uporabimo piškotke?Oto Brglez
 
Continuous integration (CI) v praksi
Continuous integration (CI) v praksiContinuous integration (CI) v praksi
Continuous integration (CI) v praksiOto Brglez
 
Ruby in prijatelji
Ruby in prijateljiRuby in prijatelji
Ruby in prijateljiOto Brglez
 
Ruby in ogrodje Rails
Ruby in ogrodje RailsRuby in ogrodje Rails
Ruby in ogrodje RailsOto Brglez
 
Subversion in Redmine implementacija
Subversion in Redmine implementacijaSubversion in Redmine implementacija
Subversion in Redmine implementacijaOto Brglez
 
mojakoda.si - predstavitev
mojakoda.si - predstavitevmojakoda.si - predstavitev
mojakoda.si - predstavitevOto Brglez
 
Šolski Spletni Informacijski Sistem
Šolski Spletni Informacijski SistemŠolski Spletni Informacijski Sistem
Šolski Spletni Informacijski SistemOto Brglez
 
PHP: Hypertext Preprocessor Introduction
PHP: Hypertext Preprocessor IntroductionPHP: Hypertext Preprocessor Introduction
PHP: Hypertext Preprocessor IntroductionOto Brglez
 
Java Servlet in JSP
Java Servlet in JSPJava Servlet in JSP
Java Servlet in JSPOto Brglez
 

More from Oto Brglez (15)

The Compression Puzzle Challenge
The Compression Puzzle ChallengeThe Compression Puzzle Challenge
The Compression Puzzle Challenge
 
Becoming S/W Engineer
Becoming S/W EngineerBecoming S/W Engineer
Becoming S/W Engineer
 
How to over-engineer things and have fun? Building a modern, distributed real...
How to over-engineer things and have fun? Building a modern, distributed real...How to over-engineer things and have fun? Building a modern, distributed real...
How to over-engineer things and have fun? Building a modern, distributed real...
 
Oto Brglez - Tips for better tests
Oto Brglez - Tips for better testsOto Brglez - Tips for better tests
Oto Brglez - Tips for better tests
 
Elasticsearch
ElasticsearchElasticsearch
Elasticsearch
 
Kdaj lahko uporabimo piškotke?
Kdaj lahko uporabimo piškotke?Kdaj lahko uporabimo piškotke?
Kdaj lahko uporabimo piškotke?
 
Continuous integration (CI) v praksi
Continuous integration (CI) v praksiContinuous integration (CI) v praksi
Continuous integration (CI) v praksi
 
nanob
nanobnanob
nanob
 
Ruby in prijatelji
Ruby in prijateljiRuby in prijatelji
Ruby in prijatelji
 
Ruby in ogrodje Rails
Ruby in ogrodje RailsRuby in ogrodje Rails
Ruby in ogrodje Rails
 
Subversion in Redmine implementacija
Subversion in Redmine implementacijaSubversion in Redmine implementacija
Subversion in Redmine implementacija
 
mojakoda.si - predstavitev
mojakoda.si - predstavitevmojakoda.si - predstavitev
mojakoda.si - predstavitev
 
Šolski Spletni Informacijski Sistem
Šolski Spletni Informacijski SistemŠolski Spletni Informacijski Sistem
Šolski Spletni Informacijski Sistem
 
PHP: Hypertext Preprocessor Introduction
PHP: Hypertext Preprocessor IntroductionPHP: Hypertext Preprocessor Introduction
PHP: Hypertext Preprocessor Introduction
 
Java Servlet in JSP
Java Servlet in JSPJava Servlet in JSP
Java Servlet in JSP
 

Recently uploaded

Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024The Digital Insurer
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Principled Technologies
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 

Recently uploaded (20)

Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 

Akka with Scala

  • 1. Akka with Scala Oto Brglez, June 2021 Gentle introduction to tomorrows tech Today.
  • 2. Oto Brglez • Engineering manager && Software Architect @ GWI • R&D Stuff => 🚀 to 🌕 • Consultant / Founder @ OPALAB => epic.blog • @otobrglez bit.ly/oto-brglez-cv * FB.com/groups/developerji
  • 3.
  • 4. Do you use this stuff?
  • 6. What kind of problem are you solving?
  • 8.
  • 9. Pollpass • Market Research platform with focus on superior experience • Conversations not surveys • Real-time && distributed • 16+ languages, X countries… • Sophisticated scripting, routing and logic • Expression engine, ASTs, piping etc… • Enterprise grade and integrated
  • 10.
  • 11.
  • 12.
  • 14. Voice
  • 15.
  • 16. Simpler Concurrent & Distributed Systems Actors and Streams let you build systems that scale up, using the resources of a server more efficiently, and out, using multiple servers. Resilient by Design Building on the principles of The Reactive Manifesto Akka allows you to write systems that self-heal and stay responsive in the face of failures. High Performance Up to 50 million msg/sec on a single machine. Small memory footprint; ~2.5 million actors per GB of heap. Elastic & Decentralized Distributed systems without single points of failure. Load balancing and adaptive routing across nodes. Event Sourcing and CQRS with Cluster Sharding. Distributed Data for eventual consistency using CRDTs. Reactive Streaming Data Asynchronous non-blocking stream processing with backpressure. Fully async and streaming HTTP server and client provides a great platform for building microservices. Streaming integrations with Alpakka. * How Actors Work?
  • 18. class PersonActor(firstName: String, lastName: String) extends Actor with ActorLogging { override def receive: Receive = { case "eat-ice-cream" => log.info(s"$firstName has started eating ice cream. ") Thread.sleep(5.seconds.toMillis) log.info(s"$firstName has eaten his ice cream. ") } } object MainApp extends App { val system = ActorSystem("first-system") val kid1: ActorRef = system.actorOf(Props(classOf[PersonActor], "Rudi", "Brglez"), "rudi") val kid2: ActorRef = system.actorOf(Props(classOf[PersonActor], "Tinkara", "Brglez"), "tinkara") val me: ActorRef = system.actorOf(Props(classOf[PersonActor], "Oto", "Brglez"), "oto") kid1 ! "eat-ice-cream" kid1 ! "eat-ice-cream" kid1 ! "eat-ice-cream" kid2 ! "eat-ice-cream" me ! "drink-beer" } Actor that represents a person 👉 “Main” 👉 }business logic AS initialisation 👉 Spawning actors{ Sending messages{ More messages{
  • 19.
  • 20. object Person { trait PersonCommand final case object EatIceCream extends PersonCommand final case object FinishedEatingIceCream extends PersonCommand def apply(firstName: String): Behavior[PersonCommand] = idle(firstName) private def idle(firstName: String): Behavior[PersonCommand] = Behaviors.receiveMessage[PersonCommand] { case EatIceCream => eatingIceCream(firstName) case _ => Behaviors.same } private def eatingIceCream(firstName: String): Behavior[PersonCommand] = Behaviors.setup { context => Behaviors.withTimers[PersonCommand] { timers => context.log.info(s"$firstName has started eating his ice-cream. ") timers.startSingleTimer(FinishedEatingIceCream, 3.seconds) Behaviors.receiveMessage { case FinishedEatingIceCream => context.log.info(s"$firstName is done with ice-cream. ") idle(firstName) case _ => context.log.info(s"$firstName: Sorry, I'm still eating,...") Behaviors.same } } } } “Idle state” 👉 “Eating state” 👉 Commands {
  • 21. object Family { sealed trait FamilyCommand final case class AddPerson(firstName: String) extends FamilyCommand final case class EatCake(firstName: String) extends FamilyCommand def apply(): Behavior[FamilyCommand] = Behaviors.receive { case (context, AddPerson(firstName)) => context.spawn(Person(firstName), firstName) Behaviors.same case (context, EatCake(firstName)) => context.child(firstName) .map(_.asInstanceOf[ActorRef[Person.PersonCommand]]) .foreach(ref => ref ! Person.EatIceCream) Behaviors.same case _ => Behaviors.unhandled } } Commands { Child is created 👉 “EatIceCream” is sent to child with given name 👉
  • 22. object MainApp extends App { val system = ActorSystem[Family.FamilyCommand](Family(), "family") system ! Family.AddPerson("Rudi") system ! Family.AddPerson("Tinkara") system ! Family.AddPerson("Oto") system ! Family.EatCake("Rudi") system ! Family.EatCake("Tinkara") system ! Family.EatCake("Rudi") system ! Family.EatCake("Tinkara") system ! "drink beer!" } 👈 💥 Won’t actually compile since AkkaTyped required proper types and Scala compiler won’t allow this “String”!
  • 24. The Weather Temperature Example ☀ 💥 Network Problems 💥 500 Error 💥 Missing tag! 💥 Out of memory 💥 Recipient is br0ken Network is still down!!! 💥
  • 25. object MainApp extends LazyLogging { def main(args: Array[String]): Unit = { implicit val system: ActorSystem = ActorSystem("temperature-system") import system.dispatcher val changeDetector: ActorRef = system.actorOf(Props(classOf[ChangeDetector]), "change-detector") Source.tick(1.seconds, 2.seconds, "Tick") .mapAsync(1) { _ => getMeasurement } .alsoTo(Sink.foreach(v => logger.info(s"Latest measurement is ${v.getOrElse("none")} "))) .mapAsync(1)(measurement => changeDetector.ask(measurement)(1.second)) .collect { case change: ChangeDetector.Changed => change } .runWith(Sink.foreach(change => logger.info(s"Temperature change from ${change.from} to ${change.to}, ${direction(change)}."))) } private def getMeasurement(implicit system: ActorSystem, ec: ExecutionContext): Future[Measurement] = for { response <- Http().singleRequest(HttpRequest(uri = ARSOLjubljanaURL)) nodes <- Unmarshal(response.entity).to[NodeSeq] measurement = (nodes "t").headOption.flatMap(_.text.toDoubleOption) } yield measurement private val direction: ChangeDetector.Changed => String = { case ChangeDetector.Changed(from, to) if to > from => "up " case ChangeDetector.Changed(from, to) if to < from => "down " case _ => "impossible." } } Every 2 seconds send “Tick” 👉 Execute request to Web Service 👉 In parallel write to output 👉 “Ask” actor to detect changes 👉 Only care about actual “changes” 👉 Run and see the changes 👉 This part is for issuing request, dealing with response and XML parsing {
  • 26. val getMeasurementsFlow: Flow[String, Measurement, NotUsed] = RestartFlow.onFailuresWithBackoff(RestartSettings(10.seconds, 30.seconds, 0.3)) { () => Flow[String].mapAsyncUnordered(1) { _ => getMeasurement } } Source.tick(1.seconds, 2.seconds, "Tick") .via(getMeasurementsFlow) .alsoTo(Sink.foreach(v => logger.info(s"Latest measurement is ${v.getOrElse("none")} "))) .mapAsync(1)(measurement => changeDetector.ask(measurement)(1.second)) .collect { case change: ChangeDetector.Changed => change } .runWith(Sink.foreach(change => logger.info(s"The temperature has changed. From ${change.from} to ${change.to}, ${direction(change)}."))) Pass “Tick” to Flow 👉 This Flow is restarted if failures occur 👉
  • 27.
  • 29. Alpakka • Data transformation: Parsing lines, JSON Framing, Compression, CSV, Text transcoding, encoding etc… • AMQP, Apache Camel, Apache Cassandra, Apache Geode, Apache Kafka, Apache Kudu, Apache Solr, Avro Parquet, AWS EventBridge, AWS DynamoDB, AWS Kinesis and Firehose, AWS Lambda, AWS S3, AWS SNS, AWS SQS, Azure Event Hubs, Azure IoT Hub, Azure Storage Queue, Couchbase, Elasticsearch, Eventuate, File, FS2, FTP, Google Common, Google Cloud BigQuery, Google Cloud Pub/Sub, Google Cloud Pub/Sub gRPC, Google Cloud Storage, Google FCM, gRPC, Hadoop Distributed File System - HDFS, HBase, HTTP, IBM Bluemix Cloud Object Storage, IBM Db2 Event Store, InfluxDB, IronMQ, JMS, MapR Database, MongoDB, MQTT, MQTT Streaming, OrientDB, Pulsar, Pravega, Server-sent Events (SSE), Slick (JDBC), Spring Web, TCP, UDP, Unix Domain Socket, … + more
  • 31. class SurveyActor(id: UUID) extends PersistentActor with ActorLogging { override def persistenceId: String = id.toString var survey: Survey = Survey() def updateState(event: Event): Unit = { event match { case NameSet(name) => survey = survey.copy(name = Some(name)) case TextNodeAppended(name) => survey = survey.copy(nodes = survey.nodes ++ List(Text(name))) } } override def receiveRecover: Receive = { case event: Event => updateState(event) case SnapshotOffer(_, surveySnapshot: Survey) => survey = surveySnapshot } override def receiveCommand: Receive = { case SetName(name) => persist(NameSet(name)) { event => updateState(event) context.system.eventStream.publish(event) } case AppendTextNode(name) => persist(TextNodeAppended(name)) { event => updateState(event) context.system.eventStream.publish(event) } case GetSurvey => sender() ! survey } } sealed trait Command sealed trait Event case class SetName(name: String) extends Command case class NameSet(name: String) extends Event case class AppendTextNode(name: String) extends Command case class TextNodeAppended(name: String) extends Event case object GetSurvey extends Command final case class Survey( name: Option[String] = None, nodes: List[Node] = List.empty[Node]) sealed trait Node case class Text(name: String) extends Node object MainApp extends App { val system: ActorSystem = ActorSystem("surveys") import system.dispatcher val s1 = system.actorOf(Props(classOf[SurveyActor], UUID.randomUUID())) s1 ! SetName("This is my first example") s1 ! SetName("First Survey V1") s1 ! AppendTextNode("Hello!") s1 ! AppendTextNode("This is example of Akka Persistence.") s1 ! SetName("Short name") s1.ask(GetSurvey)(20.seconds).onComplete { case Success(value: Survey) => println(value.asJson) } } Execute commands and persist events 👉 State from events 👉 Recovery and snapshots 👉
  • 32. Akka Cluster + Discovery
  • 33.
  • 34.
  • 35. Please, give it a try! @otobrglez otobrglez@gmail.com meetup.com/sugslo scalaslovenia.slack.com