SlideShare a Scribd company logo
1 of 54
Download to read offline
Akka Persistence Webinar
by Patrik Nordwall

@patriknw
opt-in at-least-once delivery
semantics between actors
recover application state after a crash
Akka 2.3.0 Release


"com.typesafe.akka" %% "akka-persistence-experimental" % "2.3.0"

<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-persistence-experimental_2.10</artifactId>
<version>2.3.0</version>
</dependency>
Martin Krasser

Twitter: mrt1nz

Github: krasserm
Eventsourced



akka-persistence

September 2013 - February 2014 

contractor for Typesafe
Awesome work, Martin!
storing structure
*
Purchase
Order
Line Item
Shipping
Information
storing state transitions
Cart
Created
Added 2
Socks
Added 2
Shirts
Shipping
Info Added
Akka  Persistence  Webinar
Domain Events
• things that have completed, facts
• immutable
• verbs in past tense
• CustomerRelocated
• CargoShipped
• InvoiceSent
“State transitions are an important part of our problem
space and should be modeled within our domain.”  
Greg Young, 2008
Akka  Persistence  Webinar
Benefits
• Bullet-proof auditing and historical tracing
• Support future ways of looking at data
• Performance and scalability
• Testability
• Reconstruct production scenarios
• No object-relational impedance mismatch
• Nice fit with actors
Akka  Persistence  Webinar
Command Sourcing Event Sourcing
write-ahead-log derive events from a command
same behavior during recovery as
normal operation
external interaction can be problematic
only state-changing behavior during
recovery
persisted before validation events cannot fail
allows retroactive changes to the
business logic
fixing the business logic will not
affect persisted events
naming: represent intent, imperative naming: things that have completed,
verbs in past tense
Akka  Persistence  Webinar
Consistency boundary
• An actor is a consistency boundary
• DDD Aggregate
• No distributed transactions
• eventually consistent
• compensating actions
Akka  Persistence  Webinar
Life beyond Distributed Transactions:
an Apostate’s Opinion
Position Paper
Pat Helland
“In general, application developers simply do not implement
large scalable applications assuming distributed transactions.”  
Pat Helland
http://www-­‐db.cs.wisc.edu/cidr/cidr2007/papers/cidr07p15.pdf
Processor
Eventsourced

Processor
Channel
Persistent

Channel
View
Journal
Cluster

Sharding
Building Blocks
Processor
import akka.persistence.{ Persistent, Processor }
!
class MyProcessor extends Processor {
def receive = {
case Persistent(payload, sequenceNr) =>
// message successfully written to journal
case other =>
// message not written to journal
}
}
val processor = context.actorOf(Props[MyProcessor],

name = "myProcessor")
!
processor ! Persistent("foo") // will be journaled
processor ! "bar" // will not be journaled
Processor
class InvoiceService extends Processor {
var invoices = Map.empty[String, Invoice]
!
def receive: Receive = {
case Persistent(CreateInvoice(id), _) =>
invoices = invoices.updated(id, Invoice(id))
}
}
Processor
class InvoiceService extends Processor {
var invoices = Map.empty[String, Invoice]
!
def receive: Receive = {
case Persistent(CreateInvoice(id), _) =>
invoices = invoices.updated(id, Invoice(id))
!
case Persistent(AddInvoiceItem(id, item), _) =>
invoices.get(id) match {
case Some(inv) =>
invoices = invoices.updated(id, inv.addItem(item))
case None => // TODO
}
!
case GetInvoice(id) =>
sender() ! invoices.getOrElse(id, "not found: " + id)
!
case Persistent(SendInvoiceTo(id, address), _) =>
// TODO send to the invoice printing service
}
}
Processor
case class CreateInvoice(invoiceId: String)
case class AddInvoiceItem(invoiceId: String, invoiceItem: InvoiceItem)
case class SendInvoiceTo(invoiceId: String, to: InvoiceAddress)
case class GetInvoice(invoiceId: String)
!
case class Invoice(id: String,
items: IndexedSeq[InvoiceItem] = Vector.empty) {
def addItem(item: InvoiceItem): Invoice =
copy(items = items :+ item)
}
!
case class InvoiceItem(description: String, count: Int,
amount: BigDecimal)
!
case class InvoiceAddress(name: String, street: String, city: String)
Processor Identifier


override def processorId = "my-stable-processor-id"
Default is actor path without address

/user/top/myProcessor
Don’t use anonymous processors
Akka  Persistence  Webinar
Processor
• Automatic recovery on start and restart
• Stashing until recovery completed
• Failure handling with supervisor strategy
• Might want to delete erroneous messages
What about side effects during replay?
Processor with Channel
val printingChannel = context.actorOf(Channel.props(),
name = "printingChannel")
val printingDestination = context.system / "printingService"
!
def receive: Receive = {
case p @ Persistent(SendInvoiceTo(id, address), _) =>
// send to the invoice printing service
invoices.get(id) match {
case Some(inv) =>
printingChannel ! Deliver(p.withPayload(
PrintingOrder(inv, address)), printingDestination)
invoices -= inv.id
case None => // TODO
}
}
class PrintingService extends Actor {
def receive = {
case p @ ConfirmablePersistent(payload, sequenceNr, redeliveries) =>
// ...
p.confirm()
}
}
Akka  Persistence  Webinar
EventsourcedProcessor
• Incoming messages (commands) are not persisted
• Steps:
1. Validate command
2. Create domain event and explicitly persist it
3. Update internal state, by applying the event
4. External side effects
• During recovery the internal state is updated by applying the events
• no external side effects
EventsourcedProcessor
class BlogPost extends EventsourcedProcessor {
override def receiveCommand: Receive = ???

override def receiveRecover: Receive = ???
}
EventsourcedProcessor
object BlogPost {
case class AddPost(author: String, title: String)
}
!
class BlogPost extends EventsourcedProcessor {
override def receiveCommand: Receive = ???

override def receiveRecover: Receive = ???
}
object BlogPost {
case class AddPost(author: String, title: String)
}
!
class BlogPost extends EventsourcedProcessor {
import BlogPost._
!
override def receiveCommand: Receive = {
case AddPost(author, title) =>
persist(PostAdded(author, title)) { evt =>
state = state.updated(evt)
}
}
!
override def receiveRecover: Receive = ???
}
EventsourcedProcessor
EventsourcedProcessor
object BlogPost {
case class AddPost(author: String, title: String)
!
sealed trait Event
case class PostAdded(author: String, title: String) extends Event
!
private case class State(author: String, title: String) {
def updated(evt: Event): State = evt match {
case PostAdded(author, title) => copy(author, title)
}
}
}
!
class BlogPost extends EventsourcedProcessor {
import BlogPost._
private var state = State("", “")
!
override def receiveCommand: Receive = {
case AddPost(author, title) =>
persist(PostAdded(author, title)) { evt =>
state = state.updated(evt)
}
}
!
override def receiveRecover: Receive = ???
}
EventsourcedProcessor
object BlogPost {
case class AddPost(author: String, title: String)
case class ChangeBody(body: String)
case object Publish
!
sealed trait Event
case class PostAdded(author: String, title: String) extends Event
case class BodyChanged(body: String) extends Event
case object PostPublished extends Event
!
private case class State(author: String, title: String,
body: String, published: Boolean) {
!
def updated(evt: Event): State = evt match {
case PostAdded(author, title) => copy(author, title)
case BodyChanged(b) => copy(body = b)
case PostPublished => copy(published = true)
}
}
}
EventsourcedProcessor
class BlogPost extends EventsourcedProcessor {
import BlogPost._
private var state = State("", "", "", false)
!
override def receiveCommand: Receive = {
case AddPost(author, title) =>
if (state.body == "" && author != "" && title != "")
persist(PostAdded(author, title)) { evt =>
state = state.updated(evt)
}
case ChangeBody(body) =>
if (!state.published)
persist(BodyChanged(body)) { evt =>
state = state.updated(evt)
}
case Publish =>
if (!state.published)
persist(PostPublished) { evt =>
state = state.updated(evt)
// call external web content service ...
}
}
!
override def receiveRecover: Receive = {
case evt: Event => state = state.updated(evt)
}
}
Snapshots
class MyProcessor extends Processor {
var state: Any = _
def receive = {
case "snap" => saveSnapshot(state)
case SaveSnapshotSuccess(metadata) => // ...
case SaveSnapshotFailure(metadata, reason) => // ...
}
}
Snapshots
class MyProcessor extends Processor {
var state: Any = _
def receive = {
case "snap" => saveSnapshot(state)
case SaveSnapshotSuccess(metadata) => // ...
case SaveSnapshotFailure(metadata, reason) => // ...
!
case SnapshotOffer(metadata, offeredSnapshot) => state = offeredSnapshot
case Persistent(payload, _) => // ...
}
}
Akka  Persistence  Webinar
View
• replays Persistent messages from a Processor’s journal
• query side of CQRS
• features
• auto-update interval
• Update message
• limit
• may store its own snapshots
View
class InvoiceCounter extends View {
import InvoiceCounter._
override def processorId: String = "/user/invoiceService"
override def autoUpdateInterval = 10.seconds
!
var count = 0L
!
def receive: Actor.Receive = {
case Persistent(payload: SendInvoiceTo, _) =>
count += 1
case _: Persistent =>
case GetInvoiceCount =>
sender ! InvoiceCount(count)
}
}
!
object InvoiceCounter {
case object GetInvoiceCount
case class InvoiceCount(count: Long)
}
Processor
Eventsourced

Processor
Channel
Persistent

Channel
View
Journal
Cluster

Sharding
Building Blocks
Akka  Persistence  Webinar
At-least-once delivery
sender destination
$
Akka  Persistence  Webinar
At-least-once delivery
sender destination
$
ok
$
ok
Akka  Persistence  Webinar
Channels
• re-deliver messages until confirmed
• application level confirmation
• different semantics
• duplicates may be received
• message order not retained
• after a crash and restart messages are still delivered
• listener for RedeliverFailure notifications
• recommendation: one destination per channel 

exception: replies via channel
Akka  Persistence  Webinar
Channel vs. PersistentChannel
• Channel
• use from Processor
• in-memory
• PersistentChannel
• standalone usage
• conceptually: processor + channel
• persist messages before delivering
• reply ack when persisted
• more advanced delivery flow control
Processor with Channel
class MyProcessor extends Processor {
val channel = context.actorOf(Channel.props(), name = "myChannel")
!
def receive = {
case p @ Persistent(payload, _) =>
val destination = context.system / "myDestination"
channel ! Deliver(p.withPayload("output msg"), destination)
}
}
!
class MyDestination extends Actor {
def receive = {
case p @ ConfirmablePersistent(payload, sequenceNr, redeliveries) =>
// ...
p.confirm()
}
}
PersistentChannel
class Endpoint extends Actor {
val channel = context.actorOf(PersistentChannel.props(
PersistentChannelSettings(redeliverInterval = 3.seconds, redeliverMax = 10,
replyPersistent = true)), name = "myChannel")
val destination = context.system / "jobManager"
!
import context.dispatcher
implicit val timeout = Timeout(5.seconds)
!
def receive = {
case job: Job =>
(channel ? Deliver(Persistent(job), destination)) map {
case _: Persistent => "OK: " + job.id
} recover {
case e => "FAILED: " + job.id
} pipeTo sender()
}
}
Akka  Persistence  Webinar
Serialization
• pluggable, Akka serialization
• application life-cycle, versioning
• don’t use default Java serialization
Akka  Persistence  Webinar
Journal and snapshot store
• pluggable
• LevelDB shipped with Akka – local files
• Community http://akka.io/community/
• BDB
• Cassandra
• DynamoDB
• HBase
• MapDB
• MongoDB
Akka  Persistence  Webinar
Cluster
• simple way of migrating/moving stateful actors in a cluster
• distributed journal
• shared LevelDB journal for testing
• single writer per event stream
• cluster singleton
• cluster sharding
Akka  Persistence  Webinar
Cluster Singleton
A
B
C D
Akka  Persistence  Webinar
Cluster Singleton
A
B
C
D
role: backend-1 role: backend-1
role: backend-2 role: backend-2
Akka  Persistence  Webinar
Cluster Sharding
A B
C D
Akka  Persistence  Webinar
Cluster Sharding
sender
id:17
region

node-­‐1
coordinator
region

node-­‐2
region

node-­‐3
GetShardHome:17
id:17 ShardHome:17  -­‐>  node2
17  -­‐>  node2
Akka  Persistence  Webinar
Cluster Sharding
sender region

node-­‐1
coordinator
region

node-­‐2
region

node-­‐3
id:17
id:17
GetShardHome:17
ShardHome:17  -­‐>  node2
id:17
17  -­‐>  node2
17  -­‐>  node2
Akka  Persistence  Webinar
Cluster Sharding
17
sender region

node-­‐1
coordinator
region

node-­‐2
region

node-­‐3
id:17
id:17
17  -­‐>  node2
17  -­‐>  node2
17  -­‐>  node2
Akka  Persistence  Webinar
Cluster Sharding
17
sender region

node-­‐1
coordinator
region

node-­‐2
region

node-­‐3
17  -­‐>  node2
17  -­‐>  node2
17  -­‐>  node2
id:17
Akka  Persistence  Webinar
Cluster Sharding
17
sender region

node-­‐1
coordinator
region

node-­‐2
region

node-­‐3
17  -­‐>  node2
17  -­‐>  node2
17  -­‐>  node2
id:17
Cluster Sharding
val idExtractor: ShardRegion.IdExtractor = {
case cmd: Command => (cmd.postId, cmd)
}
!
val shardResolver: ShardRegion.ShardResolver = msg => msg match {
case cmd: Command => (math.abs(cmd.postId.hashCode) % 100).toString
}
ClusterSharding(system).start(
typeName = BlogPost.shardName,
entryProps = Some(BlogPost.props()),
idExtractor = BlogPost.idExtractor,
shardResolver = BlogPost.shardResolver)
val postRegion: ActorRef = 

ClusterSharding(context.system).shardRegion(BlogPost.shardName)
!
val postId = UUID.randomUUID().toString
postRegion ! BlogPost.AddPost(postId, author, title)
Processor
Eventsourced

Processor
Channel
Persistent

Channel
View
Journal
Cluster

Sharding
Building Blocks
Akka  Persistence  Webinar
Next step
• Documentation
• http://doc.akka.io/docs/akka/2.3.0/scala/persistence.html
• http://doc.akka.io/docs/akka/2.3.0/java/persistence.html
• http://doc.akka.io/docs/akka/2.3.0/contrib/cluster-sharding.html
• Typesafe Activator
• https://typesafe.com/activator/template/akka-sample-persistence-scala
• https://typesafe.com/activator/template/akka-sample-persistence-java
• http://typesafe.com/activator/template/akka-cluster-sharding-scala
• Mailing list
• http://groups.google.com/group/akka-user
• Migration guide from Eventsourced
• http://doc.akka.io/docs/akka/2.3.0/project/migration-guide-eventsourced-2.3.x.html
Akka  Persistence  Webinar
Akka in Action
• All registrants for this webinar qualify for a free E-Book PDF subset of
Akka in Action by Raymond Roestenburg, Rob Bakker and Rob Williams.
Additionally, you will qualify for the Typesafe discount and can save 40%
on the full book.
©Typesafe 2014 – All Rights Reserved

More Related Content

What's hot

Distributed Consensus A.K.A. "What do we eat for lunch?"
Distributed Consensus A.K.A. "What do we eat for lunch?"Distributed Consensus A.K.A. "What do we eat for lunch?"
Distributed Consensus A.K.A. "What do we eat for lunch?"Konrad Malawski
 
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka StreamsFresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka StreamsKonrad Malawski
 
A Crash Course on Serverless Applications in Python
A Crash Course on Serverless Applications in PythonA Crash Course on Serverless Applications in Python
A Crash Course on Serverless Applications in PythonJames Saryerwinnie
 
Building an aws sdk for Perl - Granada Perl Workshop 2014
Building an aws sdk for Perl - Granada Perl Workshop 2014Building an aws sdk for Perl - Granada Perl Workshop 2014
Building an aws sdk for Perl - Granada Perl Workshop 2014Jose Luis Martínez
 
Webinar - How to Build Data Pipelines for Real-Time Applications with SMACK &...
Webinar - How to Build Data Pipelines for Real-Time Applications with SMACK &...Webinar - How to Build Data Pipelines for Real-Time Applications with SMACK &...
Webinar - How to Build Data Pipelines for Real-Time Applications with SMACK &...DataStax
 
CLS & asyncListener: asynchronous observability for Node.js
CLS & asyncListener: asynchronous observability for Node.jsCLS & asyncListener: asynchronous observability for Node.js
CLS & asyncListener: asynchronous observability for Node.jsForrest Norvell
 
Device Simulator with Akka
Device Simulator with AkkaDevice Simulator with Akka
Device Simulator with AkkaMax Huang
 
TLS305 Using DynamoDB with the AWS SDK for PHP - AWS re: Invent 2012
TLS305 Using DynamoDB with the AWS SDK for PHP - AWS re: Invent 2012TLS305 Using DynamoDB with the AWS SDK for PHP - AWS re: Invent 2012
TLS305 Using DynamoDB with the AWS SDK for PHP - AWS re: Invent 2012Amazon Web Services
 
The dark side of Akka and the remedy
The dark side of Akka and the remedyThe dark side of Akka and the remedy
The dark side of Akka and the remedykrivachy
 
Reactive stream processing using Akka streams
Reactive stream processing using Akka streams Reactive stream processing using Akka streams
Reactive stream processing using Akka streams Johan Andrén
 
Next generation actors with Akka
Next generation actors with AkkaNext generation actors with Akka
Next generation actors with AkkaJohan Andrén
 
Streaming all the things with akka streams
Streaming all the things with akka streams   Streaming all the things with akka streams
Streaming all the things with akka streams Johan Andrén
 
Reactive streams processing using Akka Streams
Reactive streams processing using Akka StreamsReactive streams processing using Akka Streams
Reactive streams processing using Akka StreamsJohan Andrén
 
Networks and types - the future of Akka
Networks and types - the future of AkkaNetworks and types - the future of Akka
Networks and types - the future of AkkaJohan Andrén
 
Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Ben Lesh
 
Reactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysReactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysManuel Bernhardt
 
Implementing Server Side Data Synchronization for Mobile Apps
Implementing Server Side Data Synchronization for Mobile AppsImplementing Server Side Data Synchronization for Mobile Apps
Implementing Server Side Data Synchronization for Mobile AppsMichele Orselli
 
Server side data sync for mobile apps with silex
Server side data sync for mobile apps with silexServer side data sync for mobile apps with silex
Server side data sync for mobile apps with silexMichele Orselli
 
Implementing data sync apis for mibile apps @cloudconf
Implementing data sync apis for mibile apps @cloudconfImplementing data sync apis for mibile apps @cloudconf
Implementing data sync apis for mibile apps @cloudconfMichele Orselli
 
Architecting Alive Apps
Architecting Alive AppsArchitecting Alive Apps
Architecting Alive AppsJorge Ortiz
 

What's hot (20)

Distributed Consensus A.K.A. "What do we eat for lunch?"
Distributed Consensus A.K.A. "What do we eat for lunch?"Distributed Consensus A.K.A. "What do we eat for lunch?"
Distributed Consensus A.K.A. "What do we eat for lunch?"
 
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka StreamsFresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
 
A Crash Course on Serverless Applications in Python
A Crash Course on Serverless Applications in PythonA Crash Course on Serverless Applications in Python
A Crash Course on Serverless Applications in Python
 
Building an aws sdk for Perl - Granada Perl Workshop 2014
Building an aws sdk for Perl - Granada Perl Workshop 2014Building an aws sdk for Perl - Granada Perl Workshop 2014
Building an aws sdk for Perl - Granada Perl Workshop 2014
 
Webinar - How to Build Data Pipelines for Real-Time Applications with SMACK &...
Webinar - How to Build Data Pipelines for Real-Time Applications with SMACK &...Webinar - How to Build Data Pipelines for Real-Time Applications with SMACK &...
Webinar - How to Build Data Pipelines for Real-Time Applications with SMACK &...
 
CLS & asyncListener: asynchronous observability for Node.js
CLS & asyncListener: asynchronous observability for Node.jsCLS & asyncListener: asynchronous observability for Node.js
CLS & asyncListener: asynchronous observability for Node.js
 
Device Simulator with Akka
Device Simulator with AkkaDevice Simulator with Akka
Device Simulator with Akka
 
TLS305 Using DynamoDB with the AWS SDK for PHP - AWS re: Invent 2012
TLS305 Using DynamoDB with the AWS SDK for PHP - AWS re: Invent 2012TLS305 Using DynamoDB with the AWS SDK for PHP - AWS re: Invent 2012
TLS305 Using DynamoDB with the AWS SDK for PHP - AWS re: Invent 2012
 
The dark side of Akka and the remedy
The dark side of Akka and the remedyThe dark side of Akka and the remedy
The dark side of Akka and the remedy
 
Reactive stream processing using Akka streams
Reactive stream processing using Akka streams Reactive stream processing using Akka streams
Reactive stream processing using Akka streams
 
Next generation actors with Akka
Next generation actors with AkkaNext generation actors with Akka
Next generation actors with Akka
 
Streaming all the things with akka streams
Streaming all the things with akka streams   Streaming all the things with akka streams
Streaming all the things with akka streams
 
Reactive streams processing using Akka Streams
Reactive streams processing using Akka StreamsReactive streams processing using Akka Streams
Reactive streams processing using Akka Streams
 
Networks and types - the future of Akka
Networks and types - the future of AkkaNetworks and types - the future of Akka
Networks and types - the future of Akka
 
Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016
 
Reactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysReactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDays
 
Implementing Server Side Data Synchronization for Mobile Apps
Implementing Server Side Data Synchronization for Mobile AppsImplementing Server Side Data Synchronization for Mobile Apps
Implementing Server Side Data Synchronization for Mobile Apps
 
Server side data sync for mobile apps with silex
Server side data sync for mobile apps with silexServer side data sync for mobile apps with silex
Server side data sync for mobile apps with silex
 
Implementing data sync apis for mibile apps @cloudconf
Implementing data sync apis for mibile apps @cloudconfImplementing data sync apis for mibile apps @cloudconf
Implementing data sync apis for mibile apps @cloudconf
 
Architecting Alive Apps
Architecting Alive AppsArchitecting Alive Apps
Architecting Alive Apps
 

Viewers also liked

Akka Persistence and Eventuate
Akka Persistence and EventuateAkka Persistence and Eventuate
Akka Persistence and EventuateMartin Krasser
 
Microservices in Scala: Play Framework
Microservices in Scala: Play FrameworkMicroservices in Scala: Play Framework
Microservices in Scala: Play FrameworkŁukasz Sowa
 
Deep Introduction to Akka
Deep Introduction to AkkaDeep Introduction to Akka
Deep Introduction to Akkapatriknw
 
Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015
Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015
Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015Yanik Berube
 
Codemotion akka persistence, cqrs%2 fes y otras siglas del montón
Codemotion   akka persistence, cqrs%2 fes y otras siglas del montónCodemotion   akka persistence, cqrs%2 fes y otras siglas del montón
Codemotion akka persistence, cqrs%2 fes y otras siglas del montónJavier Santos Paniego
 
Reactive programming with scala and akka
Reactive programming with scala and akkaReactive programming with scala and akka
Reactive programming with scala and akkaKnoldus Inc.
 
Event Sourcing using Akka on AWS
Event Sourcing using Akka on AWSEvent Sourcing using Akka on AWS
Event Sourcing using Akka on AWSDaniel Pfeiffer
 
CQRS+ESをAkka Persistenceを使って実装してみる。
CQRS+ESをAkka Persistenceを使って実装してみる。CQRS+ESをAkka Persistenceを使って実装してみる。
CQRS+ESをAkka Persistenceを使って実装してみる。Matsushita Satoshi
 
JavaOne: A tour of (advanced) akka features in 60 minutes [con1706]
JavaOne: A tour of (advanced) akka features in 60 minutes [con1706]JavaOne: A tour of (advanced) akka features in 60 minutes [con1706]
JavaOne: A tour of (advanced) akka features in 60 minutes [con1706]Johan Janssen
 
Akka Http , Routes, Streams with Scala
Akka Http , Routes, Streams with ScalaAkka Http , Routes, Streams with Scala
Akka Http , Routes, Streams with ScalaJerry Kuru
 
The Cloud-natives are RESTless @ JavaOne
The Cloud-natives are RESTless @ JavaOneThe Cloud-natives are RESTless @ JavaOne
The Cloud-natives are RESTless @ JavaOneKonrad Malawski
 
spray: REST on Akka (Scala Days)
spray: REST on Akka (Scala Days)spray: REST on Akka (Scala Days)
spray: REST on Akka (Scala Days)sirthias
 
Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014Konrad Malawski
 
Introduction to Actor Model and Akka
Introduction to Actor Model and AkkaIntroduction to Actor Model and Akka
Introduction to Actor Model and AkkaYung-Lin Ho
 
Practical Akka HTTP - introduction
Practical Akka HTTP - introductionPractical Akka HTTP - introduction
Practical Akka HTTP - introductionŁukasz Sowa
 

Viewers also liked (20)

Akka Persistence and Eventuate
Akka Persistence and EventuateAkka Persistence and Eventuate
Akka Persistence and Eventuate
 
Microservices in Scala: Play Framework
Microservices in Scala: Play FrameworkMicroservices in Scala: Play Framework
Microservices in Scala: Play Framework
 
Deep Introduction to Akka
Deep Introduction to AkkaDeep Introduction to Akka
Deep Introduction to Akka
 
Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015
Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015
Scala + Akka + ning/async-http-client - Vancouver Scala meetup February 2015
 
scalaphx-akka-http
scalaphx-akka-httpscalaphx-akka-http
scalaphx-akka-http
 
Codemotion akka persistence, cqrs%2 fes y otras siglas del montón
Codemotion   akka persistence, cqrs%2 fes y otras siglas del montónCodemotion   akka persistence, cqrs%2 fes y otras siglas del montón
Codemotion akka persistence, cqrs%2 fes y otras siglas del montón
 
Reactive programming with scala and akka
Reactive programming with scala and akkaReactive programming with scala and akka
Reactive programming with scala and akka
 
Akka Streams
Akka StreamsAkka Streams
Akka Streams
 
Event Sourcing using Akka on AWS
Event Sourcing using Akka on AWSEvent Sourcing using Akka on AWS
Event Sourcing using Akka on AWS
 
Akka-http
Akka-httpAkka-http
Akka-http
 
CQRS+ESをAkka Persistenceを使って実装してみる。
CQRS+ESをAkka Persistenceを使って実装してみる。CQRS+ESをAkka Persistenceを使って実装してみる。
CQRS+ESをAkka Persistenceを使って実装してみる。
 
JavaOne: A tour of (advanced) akka features in 60 minutes [con1706]
JavaOne: A tour of (advanced) akka features in 60 minutes [con1706]JavaOne: A tour of (advanced) akka features in 60 minutes [con1706]
JavaOne: A tour of (advanced) akka features in 60 minutes [con1706]
 
Akka Http , Routes, Streams with Scala
Akka Http , Routes, Streams with ScalaAkka Http , Routes, Streams with Scala
Akka Http , Routes, Streams with Scala
 
The Cloud-natives are RESTless @ JavaOne
The Cloud-natives are RESTless @ JavaOneThe Cloud-natives are RESTless @ JavaOne
The Cloud-natives are RESTless @ JavaOne
 
Akka http 2
Akka http 2Akka http 2
Akka http 2
 
Akka http
Akka httpAkka http
Akka http
 
spray: REST on Akka (Scala Days)
spray: REST on Akka (Scala Days)spray: REST on Akka (Scala Days)
spray: REST on Akka (Scala Days)
 
Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014
 
Introduction to Actor Model and Akka
Introduction to Actor Model and AkkaIntroduction to Actor Model and Akka
Introduction to Actor Model and Akka
 
Practical Akka HTTP - introduction
Practical Akka HTTP - introductionPractical Akka HTTP - introduction
Practical Akka HTTP - introduction
 

Similar to Akka persistence webinar

Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)Paco de la Cruz
 
BPM-3 Advanced Workflow Deep Dive
BPM-3 Advanced Workflow Deep DiveBPM-3 Advanced Workflow Deep Dive
BPM-3 Advanced Workflow Deep DiveAlfresco Software
 
Async all around us (promises)
Async all around us (promises)Async all around us (promises)
Async all around us (promises)Francisco Ferreira
 
Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Michael Plöd
 
Data in Motion: Streaming Static Data Efficiently
Data in Motion: Streaming Static Data EfficientlyData in Motion: Streaming Static Data Efficiently
Data in Motion: Streaming Static Data EfficientlyMartin Zapletal
 
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!JSFestUA
 
Data in Motion: Streaming Static Data Efficiently 2
Data in Motion: Streaming Static Data Efficiently 2Data in Motion: Streaming Static Data Efficiently 2
Data in Motion: Streaming Static Data Efficiently 2Martin Zapletal
 
Advanced Akka For Architects
Advanced Akka For ArchitectsAdvanced Akka For Architects
Advanced Akka For ArchitectsLightbend
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Paco de la Cruz
 
Event Sourcing - what could go wrong - Devoxx BE
Event Sourcing - what could go wrong - Devoxx BEEvent Sourcing - what could go wrong - Devoxx BE
Event Sourcing - what could go wrong - Devoxx BEAndrzej Ludwikowski
 
A Series of Fortunate Events - Drupalcon Europe, Amsterdam 2014
A Series of Fortunate Events - Drupalcon Europe, Amsterdam 2014A Series of Fortunate Events - Drupalcon Europe, Amsterdam 2014
A Series of Fortunate Events - Drupalcon Europe, Amsterdam 2014Matthias Noback
 
Using Akka Persistence to build a configuration datastore
Using Akka Persistence to build a configuration datastoreUsing Akka Persistence to build a configuration datastore
Using Akka Persistence to build a configuration datastoreAnargyros Kiourkos
 
A Series of Fortunate Events - Symfony Camp Sweden 2014
A Series of Fortunate Events - Symfony Camp Sweden 2014A Series of Fortunate Events - Symfony Camp Sweden 2014
A Series of Fortunate Events - Symfony Camp Sweden 2014Matthias Noback
 
How Not to Build a WordPress Plugin
How Not to Build a WordPress PluginHow Not to Build a WordPress Plugin
How Not to Build a WordPress PluginWill Norris
 
Azure Durable Functions (2019-03-30)
Azure Durable Functions (2019-03-30) Azure Durable Functions (2019-03-30)
Azure Durable Functions (2019-03-30) Paco de la Cruz
 
Higher Order Components and Render Props
Higher Order Components and Render PropsHigher Order Components and Render Props
Higher Order Components and Render PropsNitish Phanse
 
Overview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkOverview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkIndicThreads
 
Scala based Lift Framework
Scala based Lift FrameworkScala based Lift Framework
Scala based Lift Frameworkvhazrati
 

Similar to Akka persistence webinar (20)

Advanced redux
Advanced reduxAdvanced redux
Advanced redux
 
Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)
 
BPM-3 Advanced Workflow Deep Dive
BPM-3 Advanced Workflow Deep DiveBPM-3 Advanced Workflow Deep Dive
BPM-3 Advanced Workflow Deep Dive
 
Async all around us (promises)
Async all around us (promises)Async all around us (promises)
Async all around us (promises)
 
Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6
 
Data in Motion: Streaming Static Data Efficiently
Data in Motion: Streaming Static Data EfficientlyData in Motion: Streaming Static Data Efficiently
Data in Motion: Streaming Static Data Efficiently
 
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
 
Data in Motion: Streaming Static Data Efficiently 2
Data in Motion: Streaming Static Data Efficiently 2Data in Motion: Streaming Static Data Efficiently 2
Data in Motion: Streaming Static Data Efficiently 2
 
Advanced Akka For Architects
Advanced Akka For ArchitectsAdvanced Akka For Architects
Advanced Akka For Architects
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)
 
Event Sourcing - what could go wrong - Devoxx BE
Event Sourcing - what could go wrong - Devoxx BEEvent Sourcing - what could go wrong - Devoxx BE
Event Sourcing - what could go wrong - Devoxx BE
 
A Series of Fortunate Events - Drupalcon Europe, Amsterdam 2014
A Series of Fortunate Events - Drupalcon Europe, Amsterdam 2014A Series of Fortunate Events - Drupalcon Europe, Amsterdam 2014
A Series of Fortunate Events - Drupalcon Europe, Amsterdam 2014
 
Using Akka Persistence to build a configuration datastore
Using Akka Persistence to build a configuration datastoreUsing Akka Persistence to build a configuration datastore
Using Akka Persistence to build a configuration datastore
 
A Series of Fortunate Events - Symfony Camp Sweden 2014
A Series of Fortunate Events - Symfony Camp Sweden 2014A Series of Fortunate Events - Symfony Camp Sweden 2014
A Series of Fortunate Events - Symfony Camp Sweden 2014
 
How Not to Build a WordPress Plugin
How Not to Build a WordPress PluginHow Not to Build a WordPress Plugin
How Not to Build a WordPress Plugin
 
Azure Durable Functions (2019-03-30)
Azure Durable Functions (2019-03-30) Azure Durable Functions (2019-03-30)
Azure Durable Functions (2019-03-30)
 
Higher Order Components and Render Props
Higher Order Components and Render PropsHigher Order Components and Render Props
Higher Order Components and Render Props
 
Overview Of Lift Framework
Overview Of Lift FrameworkOverview Of Lift Framework
Overview Of Lift Framework
 
Overview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkOverview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web Framework
 
Scala based Lift Framework
Scala based Lift FrameworkScala based Lift Framework
Scala based Lift Framework
 

Recently uploaded

Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...BookNet Canada
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...Karmanjay Verma
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxAna-Maria Mihalceanu
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsYoss Cohen
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Mark Simos
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observabilityitnewsafrica
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 

Recently uploaded (20)

Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance Toolbox
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platforms
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 

Akka persistence webinar

  • 1. Akka Persistence Webinar by Patrik Nordwall
 @patriknw
  • 2. opt-in at-least-once delivery semantics between actors recover application state after a crash
  • 3. Akka 2.3.0 Release 
 "com.typesafe.akka" %% "akka-persistence-experimental" % "2.3.0"
 <dependency> <groupId>com.typesafe.akka</groupId> <artifactId>akka-persistence-experimental_2.10</artifactId> <version>2.3.0</version> </dependency>
  • 4. Martin Krasser
 Twitter: mrt1nz
 Github: krasserm Eventsourced
 
 akka-persistence
 September 2013 - February 2014 
 contractor for Typesafe Awesome work, Martin!
  • 6. storing state transitions Cart Created Added 2 Socks Added 2 Shirts Shipping Info Added
  • 7. Akka  Persistence  Webinar Domain Events • things that have completed, facts • immutable • verbs in past tense • CustomerRelocated • CargoShipped • InvoiceSent “State transitions are an important part of our problem space and should be modeled within our domain.”   Greg Young, 2008
  • 8. Akka  Persistence  Webinar Benefits • Bullet-proof auditing and historical tracing • Support future ways of looking at data • Performance and scalability • Testability • Reconstruct production scenarios • No object-relational impedance mismatch • Nice fit with actors
  • 9. Akka  Persistence  Webinar Command Sourcing Event Sourcing write-ahead-log derive events from a command same behavior during recovery as normal operation external interaction can be problematic only state-changing behavior during recovery persisted before validation events cannot fail allows retroactive changes to the business logic fixing the business logic will not affect persisted events naming: represent intent, imperative naming: things that have completed, verbs in past tense
  • 10. Akka  Persistence  Webinar Consistency boundary • An actor is a consistency boundary • DDD Aggregate • No distributed transactions • eventually consistent • compensating actions
  • 11. Akka  Persistence  Webinar Life beyond Distributed Transactions: an Apostate’s Opinion Position Paper Pat Helland “In general, application developers simply do not implement large scalable applications assuming distributed transactions.”   Pat Helland http://www-­‐db.cs.wisc.edu/cidr/cidr2007/papers/cidr07p15.pdf
  • 13. Processor import akka.persistence.{ Persistent, Processor } ! class MyProcessor extends Processor { def receive = { case Persistent(payload, sequenceNr) => // message successfully written to journal case other => // message not written to journal } } val processor = context.actorOf(Props[MyProcessor],
 name = "myProcessor") ! processor ! Persistent("foo") // will be journaled processor ! "bar" // will not be journaled
  • 14. Processor class InvoiceService extends Processor { var invoices = Map.empty[String, Invoice] ! def receive: Receive = { case Persistent(CreateInvoice(id), _) => invoices = invoices.updated(id, Invoice(id)) } }
  • 15. Processor class InvoiceService extends Processor { var invoices = Map.empty[String, Invoice] ! def receive: Receive = { case Persistent(CreateInvoice(id), _) => invoices = invoices.updated(id, Invoice(id)) ! case Persistent(AddInvoiceItem(id, item), _) => invoices.get(id) match { case Some(inv) => invoices = invoices.updated(id, inv.addItem(item)) case None => // TODO } ! case GetInvoice(id) => sender() ! invoices.getOrElse(id, "not found: " + id) ! case Persistent(SendInvoiceTo(id, address), _) => // TODO send to the invoice printing service } }
  • 16. Processor case class CreateInvoice(invoiceId: String) case class AddInvoiceItem(invoiceId: String, invoiceItem: InvoiceItem) case class SendInvoiceTo(invoiceId: String, to: InvoiceAddress) case class GetInvoice(invoiceId: String) ! case class Invoice(id: String, items: IndexedSeq[InvoiceItem] = Vector.empty) { def addItem(item: InvoiceItem): Invoice = copy(items = items :+ item) } ! case class InvoiceItem(description: String, count: Int, amount: BigDecimal) ! case class InvoiceAddress(name: String, street: String, city: String)
  • 17. Processor Identifier 
 override def processorId = "my-stable-processor-id" Default is actor path without address
 /user/top/myProcessor Don’t use anonymous processors
  • 18. Akka  Persistence  Webinar Processor • Automatic recovery on start and restart • Stashing until recovery completed • Failure handling with supervisor strategy • Might want to delete erroneous messages
  • 19. What about side effects during replay?
  • 20. Processor with Channel val printingChannel = context.actorOf(Channel.props(), name = "printingChannel") val printingDestination = context.system / "printingService" ! def receive: Receive = { case p @ Persistent(SendInvoiceTo(id, address), _) => // send to the invoice printing service invoices.get(id) match { case Some(inv) => printingChannel ! Deliver(p.withPayload( PrintingOrder(inv, address)), printingDestination) invoices -= inv.id case None => // TODO } } class PrintingService extends Actor { def receive = { case p @ ConfirmablePersistent(payload, sequenceNr, redeliveries) => // ... p.confirm() } }
  • 21. Akka  Persistence  Webinar EventsourcedProcessor • Incoming messages (commands) are not persisted • Steps: 1. Validate command 2. Create domain event and explicitly persist it 3. Update internal state, by applying the event 4. External side effects • During recovery the internal state is updated by applying the events • no external side effects
  • 22. EventsourcedProcessor class BlogPost extends EventsourcedProcessor { override def receiveCommand: Receive = ???
 override def receiveRecover: Receive = ??? }
  • 23. EventsourcedProcessor object BlogPost { case class AddPost(author: String, title: String) } ! class BlogPost extends EventsourcedProcessor { override def receiveCommand: Receive = ???
 override def receiveRecover: Receive = ??? }
  • 24. object BlogPost { case class AddPost(author: String, title: String) } ! class BlogPost extends EventsourcedProcessor { import BlogPost._ ! override def receiveCommand: Receive = { case AddPost(author, title) => persist(PostAdded(author, title)) { evt => state = state.updated(evt) } } ! override def receiveRecover: Receive = ??? } EventsourcedProcessor
  • 25. EventsourcedProcessor object BlogPost { case class AddPost(author: String, title: String) ! sealed trait Event case class PostAdded(author: String, title: String) extends Event ! private case class State(author: String, title: String) { def updated(evt: Event): State = evt match { case PostAdded(author, title) => copy(author, title) } } } ! class BlogPost extends EventsourcedProcessor { import BlogPost._ private var state = State("", “") ! override def receiveCommand: Receive = { case AddPost(author, title) => persist(PostAdded(author, title)) { evt => state = state.updated(evt) } } ! override def receiveRecover: Receive = ??? }
  • 26. EventsourcedProcessor object BlogPost { case class AddPost(author: String, title: String) case class ChangeBody(body: String) case object Publish ! sealed trait Event case class PostAdded(author: String, title: String) extends Event case class BodyChanged(body: String) extends Event case object PostPublished extends Event ! private case class State(author: String, title: String, body: String, published: Boolean) { ! def updated(evt: Event): State = evt match { case PostAdded(author, title) => copy(author, title) case BodyChanged(b) => copy(body = b) case PostPublished => copy(published = true) } } }
  • 27. EventsourcedProcessor class BlogPost extends EventsourcedProcessor { import BlogPost._ private var state = State("", "", "", false) ! override def receiveCommand: Receive = { case AddPost(author, title) => if (state.body == "" && author != "" && title != "") persist(PostAdded(author, title)) { evt => state = state.updated(evt) } case ChangeBody(body) => if (!state.published) persist(BodyChanged(body)) { evt => state = state.updated(evt) } case Publish => if (!state.published) persist(PostPublished) { evt => state = state.updated(evt) // call external web content service ... } } ! override def receiveRecover: Receive = { case evt: Event => state = state.updated(evt) } }
  • 28. Snapshots class MyProcessor extends Processor { var state: Any = _ def receive = { case "snap" => saveSnapshot(state) case SaveSnapshotSuccess(metadata) => // ... case SaveSnapshotFailure(metadata, reason) => // ... } }
  • 29. Snapshots class MyProcessor extends Processor { var state: Any = _ def receive = { case "snap" => saveSnapshot(state) case SaveSnapshotSuccess(metadata) => // ... case SaveSnapshotFailure(metadata, reason) => // ... ! case SnapshotOffer(metadata, offeredSnapshot) => state = offeredSnapshot case Persistent(payload, _) => // ... } }
  • 30. Akka  Persistence  Webinar View • replays Persistent messages from a Processor’s journal • query side of CQRS • features • auto-update interval • Update message • limit • may store its own snapshots
  • 31. View class InvoiceCounter extends View { import InvoiceCounter._ override def processorId: String = "/user/invoiceService" override def autoUpdateInterval = 10.seconds ! var count = 0L ! def receive: Actor.Receive = { case Persistent(payload: SendInvoiceTo, _) => count += 1 case _: Persistent => case GetInvoiceCount => sender ! InvoiceCount(count) } } ! object InvoiceCounter { case object GetInvoiceCount case class InvoiceCount(count: Long) }
  • 33. Akka  Persistence  Webinar At-least-once delivery sender destination $
  • 34. Akka  Persistence  Webinar At-least-once delivery sender destination $ ok $ ok
  • 35. Akka  Persistence  Webinar Channels • re-deliver messages until confirmed • application level confirmation • different semantics • duplicates may be received • message order not retained • after a crash and restart messages are still delivered • listener for RedeliverFailure notifications • recommendation: one destination per channel 
 exception: replies via channel
  • 36. Akka  Persistence  Webinar Channel vs. PersistentChannel • Channel • use from Processor • in-memory • PersistentChannel • standalone usage • conceptually: processor + channel • persist messages before delivering • reply ack when persisted • more advanced delivery flow control
  • 37. Processor with Channel class MyProcessor extends Processor { val channel = context.actorOf(Channel.props(), name = "myChannel") ! def receive = { case p @ Persistent(payload, _) => val destination = context.system / "myDestination" channel ! Deliver(p.withPayload("output msg"), destination) } } ! class MyDestination extends Actor { def receive = { case p @ ConfirmablePersistent(payload, sequenceNr, redeliveries) => // ... p.confirm() } }
  • 38. PersistentChannel class Endpoint extends Actor { val channel = context.actorOf(PersistentChannel.props( PersistentChannelSettings(redeliverInterval = 3.seconds, redeliverMax = 10, replyPersistent = true)), name = "myChannel") val destination = context.system / "jobManager" ! import context.dispatcher implicit val timeout = Timeout(5.seconds) ! def receive = { case job: Job => (channel ? Deliver(Persistent(job), destination)) map { case _: Persistent => "OK: " + job.id } recover { case e => "FAILED: " + job.id } pipeTo sender() } }
  • 39. Akka  Persistence  Webinar Serialization • pluggable, Akka serialization • application life-cycle, versioning • don’t use default Java serialization
  • 40. Akka  Persistence  Webinar Journal and snapshot store • pluggable • LevelDB shipped with Akka – local files • Community http://akka.io/community/ • BDB • Cassandra • DynamoDB • HBase • MapDB • MongoDB
  • 41. Akka  Persistence  Webinar Cluster • simple way of migrating/moving stateful actors in a cluster • distributed journal • shared LevelDB journal for testing • single writer per event stream • cluster singleton • cluster sharding
  • 43. Akka  Persistence  Webinar Cluster Singleton A B C D role: backend-1 role: backend-1 role: backend-2 role: backend-2
  • 45. Akka  Persistence  Webinar Cluster Sharding sender id:17 region
 node-­‐1 coordinator region
 node-­‐2 region
 node-­‐3 GetShardHome:17 id:17 ShardHome:17  -­‐>  node2 17  -­‐>  node2
  • 46. Akka  Persistence  Webinar Cluster Sharding sender region
 node-­‐1 coordinator region
 node-­‐2 region
 node-­‐3 id:17 id:17 GetShardHome:17 ShardHome:17  -­‐>  node2 id:17 17  -­‐>  node2 17  -­‐>  node2
  • 47. Akka  Persistence  Webinar Cluster Sharding 17 sender region
 node-­‐1 coordinator region
 node-­‐2 region
 node-­‐3 id:17 id:17 17  -­‐>  node2 17  -­‐>  node2 17  -­‐>  node2
  • 48. Akka  Persistence  Webinar Cluster Sharding 17 sender region
 node-­‐1 coordinator region
 node-­‐2 region
 node-­‐3 17  -­‐>  node2 17  -­‐>  node2 17  -­‐>  node2 id:17
  • 49. Akka  Persistence  Webinar Cluster Sharding 17 sender region
 node-­‐1 coordinator region
 node-­‐2 region
 node-­‐3 17  -­‐>  node2 17  -­‐>  node2 17  -­‐>  node2 id:17
  • 50. Cluster Sharding val idExtractor: ShardRegion.IdExtractor = { case cmd: Command => (cmd.postId, cmd) } ! val shardResolver: ShardRegion.ShardResolver = msg => msg match { case cmd: Command => (math.abs(cmd.postId.hashCode) % 100).toString } ClusterSharding(system).start( typeName = BlogPost.shardName, entryProps = Some(BlogPost.props()), idExtractor = BlogPost.idExtractor, shardResolver = BlogPost.shardResolver) val postRegion: ActorRef = 
 ClusterSharding(context.system).shardRegion(BlogPost.shardName) ! val postId = UUID.randomUUID().toString postRegion ! BlogPost.AddPost(postId, author, title)
  • 52. Akka  Persistence  Webinar Next step • Documentation • http://doc.akka.io/docs/akka/2.3.0/scala/persistence.html • http://doc.akka.io/docs/akka/2.3.0/java/persistence.html • http://doc.akka.io/docs/akka/2.3.0/contrib/cluster-sharding.html • Typesafe Activator • https://typesafe.com/activator/template/akka-sample-persistence-scala • https://typesafe.com/activator/template/akka-sample-persistence-java • http://typesafe.com/activator/template/akka-cluster-sharding-scala • Mailing list • http://groups.google.com/group/akka-user • Migration guide from Eventsourced • http://doc.akka.io/docs/akka/2.3.0/project/migration-guide-eventsourced-2.3.x.html
  • 53. Akka  Persistence  Webinar Akka in Action • All registrants for this webinar qualify for a free E-Book PDF subset of Akka in Action by Raymond Roestenburg, Rob Bakker and Rob Williams. Additionally, you will qualify for the Typesafe discount and can save 40% on the full book.
  • 54. ©Typesafe 2014 – All Rights Reserved