2. 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
3. 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
4. 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
5. 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
6. 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
7. 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
8. 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
9. 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
10. 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
11. 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
14. 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
15. 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
16. 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
17. What is Akka Persistence?
● provides reactive way of facilitating DDD/CQRS event
sourced architecture
● is implicitly event-driven
18. 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
19. 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
20. 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
21. 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 maintaining
Persistence example state
22. 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)
}
}
}
23. 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
24. 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
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.
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.
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.
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).