akka-typed中已经没有PersistentActor了。取而代之的是带有EventSourcedBehavior的actor,也就是一种专门支持EventSource模式的actor。EventSource的原理和作用在之前的博客里已经有了比较详细的介绍,这里就不再重复了。本篇直接从EventsourcedBehavior actor的具体应用开始介绍。支持EventSource应用的基本数据类型包括 指令Command, 事件Event,状态State。EventSourcing其实就是一个有限状态机fsm finite-state-machine,执行Command,产生Event,改变State,终而复始。下面是一个简单的EventSource类型定义:
trait CborSerializable {} object Cart { case class Item(name: String, price: Double) sealed trait Command extends CborSerializable sealed trait Event //commands case class AddItem(item: Item) extends Command case object PayCart extends Command //event case class ItemAdded(item: Item) extends Event case object CartPaid extends Event //state case class CartLoad(load: Set[Item] = Set.empty) val commandHandler: (CartLoad, Command) => Effect[Event,CartLoad] = { (state, cmd) => cmd match { case AddItem(item) => Effect.persist(ItemAdded(item)) case PayCart => Effect.persist(CartPaid) } } val eventHandler: (CartLoad,Event) => CartLoad = { (state,evt) => evt match { case ItemAdded(item) => val sts = state.copy(load = state.load+item) println(s"current cart loading: ${sts}") sts case CartPaid => val sts = state.copy(load = Set.empty) println(s"current cart loading: ${sts.load}") sts } } def apply(): Behavior[Command] = EventSourcedBehavior[Command,Event,CartLoad]( persistenceId = PersistenceId("10","1012"), emptyState = CartLoad(), commandHandler = commandHandler, eventHandler = eventHandler ) } object EventSource extends App { import Cart._ val cart = ActorSystem(Cart(),"shopping-cart") cart ! Cart.AddItem(Item("banana",11.20)) cart ! Cart.AddItem(Item("watermelon",4.70)) scala.io.StdIn.readLine() cart.terminate() }