SlideShare a Scribd company logo
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Akka persistence, CQRS/ES y otras
siglas del montón
Javier Santos
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
About us
Javier Santos @jpaniego
«Hay dos formas de programar sin
errores; sólo la tercera funciona»
Alan J Perlis
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
scalera.es
@scalerablog
About us
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Problem to solve
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Problem to solve
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Problem to solve
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
DDD - Domain Driven Design
● Context - The setting in which a word or statement appears that
determines its meaning
● Domain (Ontology) - The subject area to which the user applies a
program is the domain of the software
● Model - A system of abstractions that describes selected aspects of a
domain and can be used to solve problems related to that domain
● Ubiquitous language - A language structured around the domain model
and used by all team members to connect all the activities of the team
with the software
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
DDD - Domain Driven Design
● Context - The setting in which a word or statement appears that
determines its meaning
● Domain (Ontology) - The subject area to which the user applies a
program is the domain of the software
● Model - A system of abstractions that describes selected aspects of a
domain and can be used to solve problems related to that domain
● Ubiquitous language - A language structured around the domain model
and used by all team members to connect all the activities of the team
with the software
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
DDD - Domain Driven Design
● Context - The setting in which a word or statement appears that
determines its meaning
● Domain (Ontology) - The subject area to which the user applies a
program is the domain of the software
● Model - A system of abstractions that describes selected aspects of a
domain and can be used to solve problems related to that domain
● Ubiquitous language - A language structured around the domain model
and used by all team members to connect all the activities of the team
with the software
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Our domain model
case class User(
name: String,
address: Address,
credit: Double,
currentBike: Option[Id[Bike]])
case class Bike(
model: String,
battery: Bike.Battery.Status,
bikeStation: Option[Id[Station]])
case class Address(
street: String,
number: String,
zipCode: String)
case class Station(
address: Address,
maxBikeCapacity: Int,
currentCapacity: Int)
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Anemic Domain Model
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Anemic Domain Model
● Think about a domain class that only contains fields and no
methods.
● Anti-pattern against the main idea of the object-oriented
programming paradigm: combining data and process
together.
● Why not using C structs then? ¬¬
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Anemic Domain Model
case class User(
name: String,
address: Address,
credit: Double,
currentBike: Option[Id[Bike]]) {
def startRental(bike: Id[Bike]): User = {
require(
currentBike.isEmpty,"There's another rental on course.")
require(
credit > 0, "Not enough credit to start a rental.")
this.copy(currentBike = Some(bike))
}
//...
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Anemic Domain Model
//...
def finishRental(creditExpense: Double): User = {
require(
currentBike.isDefined, "There is not a rental on course.")
this.copy(
currentBike = None,
credit = credit - creditExpense)
}
}
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Aggregate
● Cluster of domain objects
● The whole block of domain objects works as a sole entity.
User Bike
Address
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Aggregate
trait Aggregate extends ...{
def id: Id[This]
}
case class Station(
address: Address,
maxBikeCapacity: Int,
currentCapacity: Int)
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Event Sourcing
● “Every change to the state of an application is captured in an event
object, and that these event objects are themselves stored in the
sequence they were applied for the same lifetime as the application state
itself” - Martin Fowler
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Event Sourcing
● The system state is the sum of the events
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Stateful[T]
trait Stateful[S] {
type This <: Stateful[S]
type Action = scalaz.State[S, Event]
val state: S
def apply(s: S): This
def update(f: Action): (This, E) = {
val (newState, e) = f(state)
(apply(newState), e)
}
}
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
scalaz.State
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
scalaz.State
● Represents a state mutation that may generate some effect.
● type State[S, Effect] = StateT[Id, S, Effect]
● Monad = composable!
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
scalaz.State
type Action[E] = scalaz.State[User, E]
def addCredit(amount: Double): Action[Double] =
State(user =>
(user.copy(credit = user.credit + amount), amount))
def rentBike(bike: Id[Bike], timesUsed: Long): Action[Long] =
State(user =>
(user.copy(currentBike = Some(bike), timesUsed + 1))
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
scalaz.State
val topUpAndRent: Action[(Double, Long)] =
for {
newCredit <- addCredit(10)
timesUsed <- rentBike(Id(“bike-1”))
} yield (newCredit, timesUsed)
val (relaxingAnn, (newCredit, bikeAge)) =
topUpAndRent(User(“Ann Bottle”, Addres(...), 0.0, None)
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Immutability perversion
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
StatefulAgg[T]
trait StateAgg[S] extends Stateful[S]{
_: PersistenActor =>
var aggState: S
def updateState(f: Action): Unit = {
val (newAgg, _) = update(f)
aggState = newAgg.state
}
}
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
StatefulAgg[T]
trait StateAgg[S] extends Stateful[S]{
_: PersistenActor =>
var aggState: S
def updateState(f: Action): Unit = {
val (newAgg, _) = update(f)
aggState = newAgg.state
}
}
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
CQRS
● Command Query Responsibility Segregation
● Main idea: “You can use a different model to update the
information than the model you use to read information”
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
CQRS
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
CQRS
trait Command[Agg] {
val to: Id[Agg]
}
trait Event
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Akka persistence
● End of 2013
● Martin Krasser
● Main idea : store the internal state of an actor
● ...BUT not directly, only through the changes the actor has
suffered.
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Akka persistence
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Akka persistence
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Akka persistence - Failure recovery
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Akka persistence - Failure recovery
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Akka persistence - Failure recovery
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Akka persistence - Failure recovery
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Snapshotting
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Snapshotting
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Persistent actors
trait PersistenceStuff extends PersistentActor{
def persistenceId: String
def receiveCommand: Receive
def receiveRecover: Receive
}
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
trait Reactive { _: Stateful[S] =>
val onEvent: Event => Action
val onSnapshot: Any => Action = {
case snapshot => State(s => (s, snapshot))
}
def asEvent(c: Command[This]): Event
}
Persistent actors
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
trait Aggregate[S] extends StateAgg[S] with Reactive with PersistentActor {
def persistenceId: String = id.id
def receiveRecover: Receive = {
case event: Event => update(onEvent(event))
case snapshot => update(onSnapshot(snapshot))
}
def receiveCommand: Receive = {
case cmd: Command[This@unchecked] =>
if (checkState(cmd))
persistAll(List(asEvent(cmd))){ event =>
update(onEvent(event))
sender ! event
}
else sender ! Nope
}
}
Persistent actors
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
case class UserAgg(state: User.Default) extends Aggregate[User] {
type This = UserAgg
def apply(s: User) = UserAgg(s)
override val onEvent = {
case e@AddedCredit(amount) =>
State(s => (s.copy(credit = s.credit+10),e))
}
def asEvent(c: Command[This]): Event = c match {
case AddCredit(_, amount) => AddedCredit(amount)
}
}
Persistent actors
boilerplate
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Persistence Queries
● Like a PersistentActor but with no Command part
● peristenceId subscription or by tag
● refreshInterval in most plugins
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Persistence Queries
val readJournal =
PersistenceQuery(system).readJournalFor[MyScaladslReadJournal](
"akka.persistence.query.my-read-journal")
// issue query to journal
val source: Source[EventEnvelope, NotUsed] =
readJournal.eventsByPersistenceId("user-1337")
// materialize stream, consuming events
implicit val mat = ActorMaterializer()
source.runForeach { event => println("Event: " + event) }
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
getOrCreate
● A new command is launched against user1...how to deliver it?
● Managers
class UserManager extends Actor {
override def receive = {
case cmd: Command[User@unchecked] =>
getOrCreate(cmd.addresse) forward cmd
}
}
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
getOrCreate
● Imagine there are 500k registered users …
● ...you create a persistent actor and deliver the just arrived
command…
● ...the actor keeps alive….
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
getOrCreate
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Passivation
● Kill the actor if it’s iddle…
trait Passivation extends PersistentActor {
import ShardRegion.Passivate
context.setReceiveTimeout(60.seconds)
override def receiveCommand = {
//…
case ReceiveTimeout =>
context.parent ! Passivate(stopMessage = Stop)
}
}
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Journal
● Different supported pluggable storages:
○ AndroidSQLite
○ BDB
○ Cassandra
○ Kafka
○ DynamoDB
○ HBase
○ MongoDB
○ …
● Why choosing a distributed database as Journal for High Availability?
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
HA : Clustering
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
HA : Clustering
● Send semantics
○ Send: The message is sent to an only cluster actor that fits in the
path. If several, the actor is chosen randomly.
clusterClient ! Send(«/user/handler», «hello»,
localAffinity = true)
○ SendToAll: The message is sent to all cluster actors that fit in the
path.
clusterClient ! SendToAll(«/user/handler», «hi»)
○ Publish: The message is sent to all topic subscribers
clusterClient ! Publish(«myTopic», «hello»)
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Partitioning : Sharding
● Study case:
○ A command is sent (in a cluster)
to aggregate1, the actor is
created in node1, the command is
processed.
○ A second command is sent (in the
same cluster) to aggregate1, but
this time the command is
received by node2, so the actor is
created there.
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Partitioning : Sharding
● It provides
○ Load balancing: In case a new is added to the cluster or
another one crashes, the total actor amount is balanced.
○ Unique actor identification, so messages that are sent to the
same actor will be forwarded to the node that handles in that
moment that shard id (previous case won’t take place)
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Partitioning : Sharding
● Semantics
○ Entry: It represents a uniquely identified entity with
persistent state (Aggregate).
○ Shard: Entry group. Experts recommend
ShardAmount = 10 x MaxNodeAmount
○ ShardRegion: Same Entry shard group.
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Partitioning : Sharding
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
#graciasCarmena
#llevameEnTuBiciceta
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Problem: eventual consistency
● Changes may take
some time
● If the user requires an
immediate update,
user views could be
updated when the
command part has
acknowledge the event
persistence (handle it
carefully...)
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Problem: Distributed transactions
● Let’s suppose credit transfer is allowed among users
● Saga Pattern: A persistent actor that represents a
transaction among aggregates
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Problem: Distributed transactions
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Problem: cluster initialization
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Problem: cluster initialization
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Problem: cluster initialization
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Problem: cluster initialization
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Problem: Testing a PersistentActor
TestActorRef + PersistentActor =
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Problem: Testing a PersistentActor
TestActorRef + PersistentActor =
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Problem : Schema evolution
● Imagine the following:
case class User(name: String, address: Address, amount: Double)
case class User(cardId: String, amount: Double, usualBike: Bike)
● Choosing proper serializers are the key (ProtoBuf, Avro, Java ser...no
way)
● Event migration (EventAdapter)
● How to:
○ add attribute
○ remove attribute
○ rename attribute
○ ...
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Lightbend approach
● Runs on JRE 1.8
● Multiple service control
● Event stream abstraction
● Easy scalability
● Java SDK ...
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Lightbend approach
● Runs on JRE 1.8
● Multiple service control
● Event stream abstraction
● Easy scalability
● Java SDK ...
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
scalera.es
@scalerablog
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
MADRID · NOV 18-19 · 2016
Scala Programming @ Madrid
Akka persistence, CQRS/ES y otras
siglas del montón
Javier Santos

More Related Content

PDF
Codemotion akka voló sobre el nido del future
PPTX
Introduction to spark
PDF
Distributed computing with spark
PDF
Railroading into Scala
PDF
Design and Implementation of the Security Graph Language
PDF
Chapter05
PDF
Spark architecture
PDF
Anatomy of Data Source API : A deep dive into Spark Data source API
Codemotion akka voló sobre el nido del future
Introduction to spark
Distributed computing with spark
Railroading into Scala
Design and Implementation of the Security Graph Language
Chapter05
Spark architecture
Anatomy of Data Source API : A deep dive into Spark Data source API

What's hot (17)

ODP
Collection advance
PDF
Spark: Taming Big Data
PDF
Time Series With OrientDB - Fosdem 2015
PDF
Chapter03b
PDF
OSDC 2016 - Chronix - A fast and efficient time series storage based on Apach...
PDF
A Tool For Big Data Analysis using Apache Spark
PDF
Geospatial Graphs made easy with OrientDB - Codemotion Spain
PDF
GeeCON Prague 2016 - Geospatial Graphs made easy with OrientDB
PDF
Introduction to dataset
PDF
Reactive programming with RxSwift
PDF
Geospatial Graphs made easy with OrientDB - Codemotion Milan 2016
PDF
Laskar: High-Velocity GraphQL & Lambda-based Software Development Model
PDF
Scheme 核心概念(一)
PDF
Performant APIs with GraphQL and PHP (Dutch PHP 2019)
PDF
Extending Spark for Qbeast's SQL Data Source​ with Paola Pardo and Cesare Cug...
PDF
RxJava in practice
PDF
Cassandra for impatients
Collection advance
Spark: Taming Big Data
Time Series With OrientDB - Fosdem 2015
Chapter03b
OSDC 2016 - Chronix - A fast and efficient time series storage based on Apach...
A Tool For Big Data Analysis using Apache Spark
Geospatial Graphs made easy with OrientDB - Codemotion Spain
GeeCON Prague 2016 - Geospatial Graphs made easy with OrientDB
Introduction to dataset
Reactive programming with RxSwift
Geospatial Graphs made easy with OrientDB - Codemotion Milan 2016
Laskar: High-Velocity GraphQL & Lambda-based Software Development Model
Scheme 核心概念(一)
Performant APIs with GraphQL and PHP (Dutch PHP 2019)
Extending Spark for Qbeast's SQL Data Source​ with Paola Pardo and Cesare Cug...
RxJava in practice
Cassandra for impatients
Ad

Viewers also liked (20)

PDF
Event-sourced architectures with Akka
PDF
scalaphx-akka-http
PPTX
Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015
PDF
Akka persistence webinar
ODP
Akka Persistence | Event Sourcing
ODP
Reactive programming with scala and akka
PDF
Akka Streams
PDF
Event Sourcing using Akka on AWS
PPTX
Akka-http
PPTX
CQRS+ESをAkka Persistenceを使って実装してみる。
PPTX
JavaOne: A tour of (advanced) akka features in 60 minutes [con1706]
PDF
Akka Http , Routes, Streams with Scala
PDF
Arquitectura Lambda
PDF
DDDing Tools = Akka Persistence
PDF
The Cloud-natives are RESTless @ JavaOne
PDF
Akka http 2
ODP
Akka http
PDF
Akka Persistence and Eventuate
KEY
spray: REST on Akka (Scala Days)
PDF
Reactive Streams / Akka Streams - GeeCON Prague 2014
Event-sourced architectures with Akka
scalaphx-akka-http
Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015
Akka persistence webinar
Akka Persistence | Event Sourcing
Reactive programming with scala and akka
Akka Streams
Event Sourcing using Akka on AWS
Akka-http
CQRS+ESをAkka Persistenceを使って実装してみる。
JavaOne: A tour of (advanced) akka features in 60 minutes [con1706]
Akka Http , Routes, Streams with Scala
Arquitectura Lambda
DDDing Tools = Akka Persistence
The Cloud-natives are RESTless @ JavaOne
Akka http 2
Akka http
Akka Persistence and Eventuate
spray: REST on Akka (Scala Days)
Reactive Streams / Akka Streams - GeeCON Prague 2014
Ad

Similar to Codemotion akka persistence, cqrs%2 fes y otras siglas del montón (20)

PPTX
Taxonomy of Scala
PDF
The Scala Programming Language
PPTX
An introduction to scala
PDF
Resilient Applications with Akka Persistence - Scaladays 2014
PDF
Using Akka Persistence to build a configuration datastore
PDF
Scala in Model-Driven development for Apparel Cloud Platform
PDF
Monads and Monoids by Oleksiy Dyagilev
PPTX
Concurrency Constructs Overview
PDF
A Survey of Concurrency Constructs
PDF
Event-sourced architectures with Akka - Sander Mak
PPTX
Scala, Play 2.0 & Cloud Foundry
PDF
Andrzej Ludwikowski - Event Sourcing - what could possibly go wrong? - Codemo...
PPT
Scala - brief intro
PPTX
Indic threads pune12-typesafe stack software development on the jvm
PDF
Event Sourcing - what could possibly go wrong?
PDF
Scala Days Highlights | BoldRadius
PDF
Getting Started With Scala
PDF
Getting Started With Scala
PDF
Scala Paradigms
PDF
Akka persistence == event sourcing in 30 minutes
Taxonomy of Scala
The Scala Programming Language
An introduction to scala
Resilient Applications with Akka Persistence - Scaladays 2014
Using Akka Persistence to build a configuration datastore
Scala in Model-Driven development for Apparel Cloud Platform
Monads and Monoids by Oleksiy Dyagilev
Concurrency Constructs Overview
A Survey of Concurrency Constructs
Event-sourced architectures with Akka - Sander Mak
Scala, Play 2.0 & Cloud Foundry
Andrzej Ludwikowski - Event Sourcing - what could possibly go wrong? - Codemo...
Scala - brief intro
Indic threads pune12-typesafe stack software development on the jvm
Event Sourcing - what could possibly go wrong?
Scala Days Highlights | BoldRadius
Getting Started With Scala
Getting Started With Scala
Scala Paradigms
Akka persistence == event sourcing in 30 minutes

Recently uploaded (20)

PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
System and Network Administraation Chapter 3
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
Digital Strategies for Manufacturing Companies
PPTX
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
AI in Product Development-omnex systems
PPTX
history of c programming in notes for students .pptx
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
top salesforce developer skills in 2025.pdf
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PPTX
Online Work Permit System for Fast Permit Processing
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
System and Network Administraation Chapter 3
How Creative Agencies Leverage Project Management Software.pdf
Navsoft: AI-Powered Business Solutions & Custom Software Development
Digital Strategies for Manufacturing Companies
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
Adobe Illustrator 28.6 Crack My Vision of Vector Design
AI in Product Development-omnex systems
history of c programming in notes for students .pptx
How to Choose the Right IT Partner for Your Business in Malaysia
top salesforce developer skills in 2025.pdf
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
Online Work Permit System for Fast Permit Processing
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PTS Company Brochure 2025 (1).pdf.......
Softaken Excel to vCard Converter Software.pdf
Which alternative to Crystal Reports is best for small or large businesses.pdf
Lecture 3: Operating Systems Introduction to Computer Hardware Systems

Codemotion akka persistence, cqrs%2 fes y otras siglas del montón

  • 1. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Akka persistence, CQRS/ES y otras siglas del montón Javier Santos
  • 2. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid About us Javier Santos @jpaniego «Hay dos formas de programar sin errores; sólo la tercera funciona» Alan J Perlis
  • 3. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid scalera.es @scalerablog About us
  • 4. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Problem to solve
  • 5. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Problem to solve
  • 6. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Problem to solve
  • 7. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid DDD - Domain Driven Design ● Context - The setting in which a word or statement appears that determines its meaning ● Domain (Ontology) - The subject area to which the user applies a program is the domain of the software ● Model - A system of abstractions that describes selected aspects of a domain and can be used to solve problems related to that domain ● Ubiquitous language - A language structured around the domain model and used by all team members to connect all the activities of the team with the software
  • 8. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid DDD - Domain Driven Design ● Context - The setting in which a word or statement appears that determines its meaning ● Domain (Ontology) - The subject area to which the user applies a program is the domain of the software ● Model - A system of abstractions that describes selected aspects of a domain and can be used to solve problems related to that domain ● Ubiquitous language - A language structured around the domain model and used by all team members to connect all the activities of the team with the software
  • 9. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid DDD - Domain Driven Design ● Context - The setting in which a word or statement appears that determines its meaning ● Domain (Ontology) - The subject area to which the user applies a program is the domain of the software ● Model - A system of abstractions that describes selected aspects of a domain and can be used to solve problems related to that domain ● Ubiquitous language - A language structured around the domain model and used by all team members to connect all the activities of the team with the software
  • 10. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Our domain model case class User( name: String, address: Address, credit: Double, currentBike: Option[Id[Bike]]) case class Bike( model: String, battery: Bike.Battery.Status, bikeStation: Option[Id[Station]]) case class Address( street: String, number: String, zipCode: String) case class Station( address: Address, maxBikeCapacity: Int, currentCapacity: Int)
  • 11. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Anemic Domain Model
  • 12. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Anemic Domain Model ● Think about a domain class that only contains fields and no methods. ● Anti-pattern against the main idea of the object-oriented programming paradigm: combining data and process together. ● Why not using C structs then? ¬¬
  • 13. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Anemic Domain Model case class User( name: String, address: Address, credit: Double, currentBike: Option[Id[Bike]]) { def startRental(bike: Id[Bike]): User = { require( currentBike.isEmpty,"There's another rental on course.") require( credit > 0, "Not enough credit to start a rental.") this.copy(currentBike = Some(bike)) } //...
  • 14. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Anemic Domain Model //... def finishRental(creditExpense: Double): User = { require( currentBike.isDefined, "There is not a rental on course.") this.copy( currentBike = None, credit = credit - creditExpense) } }
  • 15. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Aggregate ● Cluster of domain objects ● The whole block of domain objects works as a sole entity. User Bike Address
  • 16. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Aggregate trait Aggregate extends ...{ def id: Id[This] } case class Station( address: Address, maxBikeCapacity: Int, currentCapacity: Int)
  • 17. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Event Sourcing ● “Every change to the state of an application is captured in an event object, and that these event objects are themselves stored in the sequence they were applied for the same lifetime as the application state itself” - Martin Fowler
  • 18. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Event Sourcing ● The system state is the sum of the events
  • 19. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Stateful[T] trait Stateful[S] { type This <: Stateful[S] type Action = scalaz.State[S, Event] val state: S def apply(s: S): This def update(f: Action): (This, E) = { val (newState, e) = f(state) (apply(newState), e) } }
  • 20. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid scalaz.State
  • 21. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid scalaz.State ● Represents a state mutation that may generate some effect. ● type State[S, Effect] = StateT[Id, S, Effect] ● Monad = composable!
  • 22. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid scalaz.State type Action[E] = scalaz.State[User, E] def addCredit(amount: Double): Action[Double] = State(user => (user.copy(credit = user.credit + amount), amount)) def rentBike(bike: Id[Bike], timesUsed: Long): Action[Long] = State(user => (user.copy(currentBike = Some(bike), timesUsed + 1))
  • 23. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid scalaz.State val topUpAndRent: Action[(Double, Long)] = for { newCredit <- addCredit(10) timesUsed <- rentBike(Id(“bike-1”)) } yield (newCredit, timesUsed) val (relaxingAnn, (newCredit, bikeAge)) = topUpAndRent(User(“Ann Bottle”, Addres(...), 0.0, None)
  • 24. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Immutability perversion
  • 25. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid StatefulAgg[T] trait StateAgg[S] extends Stateful[S]{ _: PersistenActor => var aggState: S def updateState(f: Action): Unit = { val (newAgg, _) = update(f) aggState = newAgg.state } }
  • 26. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid StatefulAgg[T] trait StateAgg[S] extends Stateful[S]{ _: PersistenActor => var aggState: S def updateState(f: Action): Unit = { val (newAgg, _) = update(f) aggState = newAgg.state } }
  • 27. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid
  • 28. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid CQRS ● Command Query Responsibility Segregation ● Main idea: “You can use a different model to update the information than the model you use to read information”
  • 29. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid CQRS
  • 30. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid CQRS trait Command[Agg] { val to: Id[Agg] } trait Event
  • 31. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Akka persistence ● End of 2013 ● Martin Krasser ● Main idea : store the internal state of an actor ● ...BUT not directly, only through the changes the actor has suffered.
  • 32. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Akka persistence
  • 33. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Akka persistence
  • 34. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Akka persistence - Failure recovery
  • 35. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Akka persistence - Failure recovery
  • 36. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Akka persistence - Failure recovery
  • 37. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Akka persistence - Failure recovery
  • 38. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Snapshotting
  • 39. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Snapshotting
  • 40. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Persistent actors trait PersistenceStuff extends PersistentActor{ def persistenceId: String def receiveCommand: Receive def receiveRecover: Receive }
  • 41. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid trait Reactive { _: Stateful[S] => val onEvent: Event => Action val onSnapshot: Any => Action = { case snapshot => State(s => (s, snapshot)) } def asEvent(c: Command[This]): Event } Persistent actors
  • 42. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid trait Aggregate[S] extends StateAgg[S] with Reactive with PersistentActor { def persistenceId: String = id.id def receiveRecover: Receive = { case event: Event => update(onEvent(event)) case snapshot => update(onSnapshot(snapshot)) } def receiveCommand: Receive = { case cmd: Command[This@unchecked] => if (checkState(cmd)) persistAll(List(asEvent(cmd))){ event => update(onEvent(event)) sender ! event } else sender ! Nope } } Persistent actors
  • 43. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid case class UserAgg(state: User.Default) extends Aggregate[User] { type This = UserAgg def apply(s: User) = UserAgg(s) override val onEvent = { case e@AddedCredit(amount) => State(s => (s.copy(credit = s.credit+10),e)) } def asEvent(c: Command[This]): Event = c match { case AddCredit(_, amount) => AddedCredit(amount) } } Persistent actors boilerplate
  • 44. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Persistence Queries ● Like a PersistentActor but with no Command part ● peristenceId subscription or by tag ● refreshInterval in most plugins
  • 45. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Persistence Queries val readJournal = PersistenceQuery(system).readJournalFor[MyScaladslReadJournal]( "akka.persistence.query.my-read-journal") // issue query to journal val source: Source[EventEnvelope, NotUsed] = readJournal.eventsByPersistenceId("user-1337") // materialize stream, consuming events implicit val mat = ActorMaterializer() source.runForeach { event => println("Event: " + event) }
  • 46. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid getOrCreate ● A new command is launched against user1...how to deliver it? ● Managers class UserManager extends Actor { override def receive = { case cmd: Command[User@unchecked] => getOrCreate(cmd.addresse) forward cmd } }
  • 47. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid getOrCreate ● Imagine there are 500k registered users … ● ...you create a persistent actor and deliver the just arrived command… ● ...the actor keeps alive….
  • 48. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid getOrCreate
  • 49. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Passivation ● Kill the actor if it’s iddle… trait Passivation extends PersistentActor { import ShardRegion.Passivate context.setReceiveTimeout(60.seconds) override def receiveCommand = { //… case ReceiveTimeout => context.parent ! Passivate(stopMessage = Stop) } }
  • 50. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid
  • 51. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Journal ● Different supported pluggable storages: ○ AndroidSQLite ○ BDB ○ Cassandra ○ Kafka ○ DynamoDB ○ HBase ○ MongoDB ○ … ● Why choosing a distributed database as Journal for High Availability?
  • 52. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid HA : Clustering
  • 53. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid HA : Clustering ● Send semantics ○ Send: The message is sent to an only cluster actor that fits in the path. If several, the actor is chosen randomly. clusterClient ! Send(«/user/handler», «hello», localAffinity = true) ○ SendToAll: The message is sent to all cluster actors that fit in the path. clusterClient ! SendToAll(«/user/handler», «hi») ○ Publish: The message is sent to all topic subscribers clusterClient ! Publish(«myTopic», «hello»)
  • 54. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Partitioning : Sharding ● Study case: ○ A command is sent (in a cluster) to aggregate1, the actor is created in node1, the command is processed. ○ A second command is sent (in the same cluster) to aggregate1, but this time the command is received by node2, so the actor is created there.
  • 55. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Partitioning : Sharding ● It provides ○ Load balancing: In case a new is added to the cluster or another one crashes, the total actor amount is balanced. ○ Unique actor identification, so messages that are sent to the same actor will be forwarded to the node that handles in that moment that shard id (previous case won’t take place)
  • 56. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Partitioning : Sharding ● Semantics ○ Entry: It represents a uniquely identified entity with persistent state (Aggregate). ○ Shard: Entry group. Experts recommend ShardAmount = 10 x MaxNodeAmount ○ ShardRegion: Same Entry shard group.
  • 57. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Partitioning : Sharding
  • 58. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid #graciasCarmena #llevameEnTuBiciceta
  • 59. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Problem: eventual consistency ● Changes may take some time ● If the user requires an immediate update, user views could be updated when the command part has acknowledge the event persistence (handle it carefully...)
  • 60. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Problem: Distributed transactions ● Let’s suppose credit transfer is allowed among users ● Saga Pattern: A persistent actor that represents a transaction among aggregates
  • 61. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Problem: Distributed transactions
  • 62. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Problem: cluster initialization
  • 63. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Problem: cluster initialization
  • 64. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Problem: cluster initialization
  • 65. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Problem: cluster initialization
  • 66. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Problem: Testing a PersistentActor TestActorRef + PersistentActor =
  • 67. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Problem: Testing a PersistentActor TestActorRef + PersistentActor =
  • 68. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Problem : Schema evolution ● Imagine the following: case class User(name: String, address: Address, amount: Double) case class User(cardId: String, amount: Double, usualBike: Bike) ● Choosing proper serializers are the key (ProtoBuf, Avro, Java ser...no way) ● Event migration (EventAdapter) ● How to: ○ add attribute ○ remove attribute ○ rename attribute ○ ...
  • 69. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Lightbend approach ● Runs on JRE 1.8 ● Multiple service control ● Event stream abstraction ● Easy scalability ● Java SDK ...
  • 70. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Lightbend approach ● Runs on JRE 1.8 ● Multiple service control ● Event stream abstraction ● Easy scalability ● Java SDK ...
  • 71. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid scalera.es @scalerablog
  • 72. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid
  • 73. MADRID · NOV 18-19 · 2016 Scala Programming @ Madrid Akka persistence, CQRS/ES y otras siglas del montón Javier Santos