by defining it's protocol sealed trait Message final case class SayHello(name: String) extends Message final case class ChangeGreeting(greet: String) extends Message
just a Behavior function def behavior(greeting: String) Behavior[Message] = Behaviors.receiveMessage { case SayHello(name) println(s"$greeting $name!") Behaviors.same case ChangeGreeting(greet) behavior(greet) }
you need to reply to an ask, your incoming message must have an ActorRef[R] that you can use to reply to. final case class Hello(msg: String) final case class SayHello(name: String, replyTo: ActorRef[Hello]) def behavior(greeting: String) Behavior[SayHello] = Behaviors.receiveMessage { case SayHello(name, replyTo) replyTo ! Hello(s"$greeting $name!") Behaviors.same }
terms of Command, Event and State • EventSourcedBehavior instead of Behavior • Tagging function • Better controlled snapshotting (number of events and/or predicate) • Enforced Replies • Old plugins are still compatible • Akka Persistence Query untouched, already typed and based on Akka Streams
Deposit(amount: Double) extends AccountCommand final case class Withdraw(amount: Double) extends AccountCommand case class GetBalance(replyTo: ActorRef[Balance]) extends AccountCommand sealed trait AccountEvent final case class Deposited(amount: Double) extends AccountEvent final case class Withdrawn(amount: Double) extends AccountEvent case class Account(balance: Double)
AccountEvent, Account]( persistenceId = PersistenceId("Account", id), emptyState = Account(balance = 0), commandHandler = (account, cmd) account.applyCommand(cmd), eventHandler = (account, evt) account.applyEvent(evt) ) save a snapshot on every 100 events and keep max 2 .withRetention(RetentionCriteria.snapshotEvery(numberOfEvents = 100, keepNSnapshots = 2)) save a snapshot when a predicate holds .snapshotWhen { case (account, evt: Withdrawn, seqNr) true case _ false } }
• Knows where is your instance • Honours single writer principle for Persistence • Entity Passivation • Rolling updates without downtime • Commands must be serializable
• Types everywhere • And functions • Any Unit is part of the past • Event Sourcing opens the door for decoupling your services • High throughput with append only journals • Scalability with Cluster Sharding • Rolling updates when clustered • Distributed event consuming (included in Lagom, will be extracted)