akka persistence | event sourcing
TRANSCRIPT
Akka Persistence | Event Sourcing
Sidharth KhattriSenior Software ConsultantKnoldus Software
Agenda
What is Event Sourcing
What are Domain Events
What are Commands
What is CQRS
When to use Event Sourcing
What is Akka Persistence
Command side of Akka Persistence
Agenda
What is Event Sourcing
What are Domain Events
What are Commands
What is CQRS
When to use Event Sourcing
What is Akka Persistence
Command side of Akka Persistence
What is Event Sourcing?
storing all changes of a system as event log
changes here means Domain Events
changes are persisted in Event Store
event store is append only storage
no updates to Event Store, they're immutable
event log can be replayed to construct current state
In systems built around event sourcing, everything that happens (events) is persisted is a event log instead of just persisting the current state. An event log is a place which records all the events that happened in a system.
Agenda
What is Event Sourcing
What are Domain Events
What are Commands
What is CQRS
When to use Event Sourcing
What is Akka Persistence
Command side of Akka Persistence
What are Domain Events?
something that already took place in a system
named as past-participle verbs
statement of facts
data transfer objects DTOs
immutable, because they're facts
represents state change in a system
Event is something that took place in a domain. These are always named with a past-participle verb, example EmailChanged. Since it is something that has already happened it can be considered as a statement of fact. Both Events and Commands are DTOs (Data transfer objects) and both are immutable. Events are immutable because they represent domain actions that happened in the past.
Agenda
What is Event Sourcing
What are Domain Events
What are Commands
What is CQRS
When to use Event Sourcing
What is Akka Persistence
Command side of Akka Persistence
What are Commands?
something that triggers a Domain Event
named as imperative verbs
are requests but not statement of facts
data transfer objects DTOs
immutable, because they're are triggers
can be rejected
Command is something which makes the Event happen. It is used to request changes to the Domain. Since it is a request it can be rejected, it is not a statement of fact. It is a verb with imperative mood. Both Events and Commands are DTOs (Data transfer objects) and both are immutable. Commands are immutable because their only usage is to be sent from the client to server side to trigger and event.
Agenda
What is Event Sourcing
What are Domain Events
What are Commands
What is CQRS
When to use Event Sourcing
What is Akka Persistence
Command side of Akka Persistence
What is CQRS?
CQRS stands for command query responsibility segregation
commands as write sides and query as read sides
commands involve domain model interaction
queries involve reporting module interaction
What is CQRS?
aggregate roots receives Commands and publish Events
aggregate is a group of associated objects
an aggregate has one root, which is an Entity
aggregate root is the only object accessible from outside world
Architecture Without CQRS
Architecture With CQRS
Agenda
What is Event Sourcing
What are Domain Events
What are Commands
What is CQRS
When to use Event Sourcing
What is Akka Persistence
Command side of Akka Persistence
When to use Event Sourcing?
when keeping audit/event logs have great significance
for building scalable systems
for predicting future needs based on event logs
for better debugging
Agenda
What is Event Sourcing
What are Domain Events
What are Commands
What is CQRS
When to use Event Sourcing
What is Akka Persistence
Command side of Akka Persistence
What is Akka Persistence?
provides reactive way of facilitating DDD/CQRS event sourced architecture
is implicitly event-driven
Agenda
What is Event Sourcing
What are Domain Events
What are Commands
What is CQRS
When to use Event Sourcing
What is Akka Persistence
Command side of Akka Persistence
What is PersistenceActor?
PersistenceActor is a trait which supports Event Sourcing
it can act as an Aggregate Root (AR) for DDD
its behavior is defined by receiveRecover and receiveCommand
receiveCommand acts as command handler
receiveRecover helps in replaying events
Command side of Akka Persistence
Command case class CreateUser(id: String, firstName: String, lastName: String, email: String)
Event case class UserCreated(id: String, firstName: String, lastName: String, email: String)
Imperative verb
Immutable
Past-participle verb
Immutable
object Protocols { case class Command(data: String) case class Event(data: String)}
final case class ExampleState(events: List[String] = Nil) { def updated(event: Event): ExampleState = copy(event.data :: events)
def size: Int = events.length
override def toString: String = events.reverse.toString()}
Persistence example protocols
For maintainingPersistence example state
class PersistenceExample extends PersistenceActor with ActorLogging { override def persistenceId: String = "persistence-example-1" var state = ExampleState()
def updateState(event: Event): Unit = state = state.updated(event)
def numEvents: Int = state.size val receiveRecover: Receive = { case event: Event => updateState(event) }
val receiveCommand: Receive = { case Command(data) => persist(Event(s"$data-${numEvents + 1}")) { event => updateState(event) } }}
Successfully persisted events are internally sent back to the persistent actor as individual messages that trigger event handler executions. An event handler may close over persistent actor state and mutate it. The sender of a persisted event is the sender of the corresponding command. This allows event handlers to reply to the sender of a command (not shown).
PersistenceActor Details
persistenceId method id of entity for which events should be replayed remains same across different actor incarnations
persist method
persists events asynchronously handler is only called on successful persistence between call to persist and execution of handler no new commands are received event handlers can update state, notify listeners and reply senders
PersistenceActor Details
override def recovery = Recovery(toSequenceNr = 457)
recovery method journals are automatically recovered on start and restart new messages sent to persistence actor during recovery do not interfere with replayed messages recovery can be disabled by using Recovery.none() initialization after recovery can be done can be done by handling RecoveryCompleted
References
http://doc.akka.io/docs/akka/2.4.0/scala/persistence.html
http://martinfowler.com/eaaDev/EventSourcing.html
http://cqrs.nu/faq
https://github.com/ironfish/akka-persistence-mongo-samples
http://pkaczor.blogspot.in/2014/04/reactive-ddd-with-akka.html
Thank You