项目作者: evolution-gaming

项目描述 :
Safe Akka
高级语言: Scala
项目地址: git://github.com/evolution-gaming/safe-akka.git
创建时间: 2017-11-23T14:15:17Z
项目社区:https://github.com/evolution-gaming/safe-akka

开源协议:MIT License

下载


Safe Akka

Build Status
Coverage Status
Codacy Badge
Version
License: MIT

This library provides abstraction on top of akka actors in order to add more type safety

Actor example

  1. import com.evolutiongaming.safeakka.actor._
  2. val ref = SafeActorRef(_ => (counter(0), ActorLog.empty))
  3. ref ! Msg.Inc
  4. ref ! Msg.Dec
  5. ref ! PoisonPill
  6. // ref ! "test" - does not compile
  7. def counter(state: Int): Behavior[Msg] = Behavior.onMsg[Msg] {
  8. case Signal.Msg(msg, sender) =>
  9. val result = msg match {
  10. case Msg.Inc => state + 1
  11. case Msg.Dec => state - 1
  12. }
  13. sender ! result
  14. counter(result)
  15. }
  16. sealed trait Msg
  17. object Msg {
  18. case object Inc extends Msg
  19. case object Dec extends Msg
  20. }

PersistentActor example

  1. def persistenceSetup(ctx: ActorCtx) = {
  2. ctx.setReceiveTimeout(300.millis)
  3. new PersistenceSetup[Counter, Counter, Cmd, Event] {
  4. val persistenceId = UUID.randomUUID().toString
  5. val log = ActorLog.empty
  6. def journalId = None
  7. def snapshotId = None
  8. def onRecoveryStarted(
  9. offer: Option[SnapshotOffer[Counter]],
  10. journaller: Journaller,
  11. snapshotter: Snapshotter[Counter]) = new Recovering {
  12. def state = offer map { _.snapshot } getOrElse Counter(0, 0)
  13. def eventHandler(state: Counter, event: Event, seqNr: SeqNr) = state(event, seqNr)
  14. def onCompleted(state: Counter, seqNr: SeqNr) = {
  15. def behavior(counter: Counter): Behavior[Cmd, Event] = Behavior[Cmd, Event] { (signal, _) =>
  16. signal match {
  17. case signal: PersistenceSignal.System =>
  18. testActor.tell(signal, ctx.self)
  19. signal match {
  20. case PersistenceSignal.Sys(Signal.RcvTimeout) => ctx.setReceiveTimeout(Duration.Inf)
  21. case _ =>
  22. }
  23. behavior(counter)
  24. case PersistenceSignal.Cmd(cmd, sender) =>
  25. def onEvent(event: Event) = {
  26. val record = Record.of(event)(_ => sender.tell(event, ctx.self))
  27. val onPersisted = (seqNr: SeqNr) => {
  28. val newCounter = counter(event, seqNr)
  29. sender.tell(newCounter, ctx.self)
  30. if (cmd == Cmd.Dec) snapshotter.save(seqNr, newCounter)
  31. behavior(newCounter)
  32. }
  33. val onFailure = (failure: Throwable) => {
  34. sender.tell(Status.Failure(failure), ctx.self)
  35. }
  36. Behavior.persist(Nel(record), onPersisted, onFailure)
  37. }
  38. cmd match {
  39. case Cmd.Inc => onEvent(Event.Inc)
  40. case Cmd.Dec => onEvent(Event.Dec)
  41. case Cmd.Stop => Behavior.stop
  42. case Cmd.Get =>
  43. sender.tell(counter, ctx.self)
  44. behavior(counter)
  45. }
  46. }
  47. }
  48. behavior(state)
  49. }
  50. def onStopped(state: Counter, seqNr: SeqNr) = {}
  51. }
  52. def onStopped(seqNr: SeqNr): Unit = {}
  53. }
  54. }
  55. val ref = PersistentActorRef(persistenceSetup)
  56. ref ! Cmd.Get
  57. ref ! Cmd.Inc
  58. ref ! Cmd.Dec
  59. ref ! Cmd.Stop

See CounterSpec

Setup

  1. addSbtPlugin("com.evolution" % "sbt-artifactory-plugin" % "0.0.2")
  2. libraryDependencies += "com.evolutiongaming" %% "safe-actor" % "3.1.0"
  3. libraryDependencies += "com.evolutiongaming" %% "safe-persistence" % "3.1.0"
  4. libraryDependencies += "com.evolutiongaming" %% "safe-persistence-async" % "3.1.0"
  5. libraryDependencies += "com.evolutiongaming" %% "safe-persistence-testkit" % "3.1.0"