为什么这个持久的演员不起作用

时间:2016-03-30 15:56:08

标签: scala akka

以下是代码:

import akka.persistence._
import akka.actor.{Actor, ActorRef, ActorSystem, Props, ActorLogging}


class Counter extends PersistentActor with ActorLogging {

  import Counter._

  var state: State = new State(0)

  override def receiveRecover: Receive = {
    case RecoveryCompleted => println("Recovery completed.")
    case SnapshotOffer(_, snapshot: State) => state = snapshot
    case op: Operation => updateState(op)
  }


  override def persistenceId: String = "counter-persistent"

  override def receiveCommand: Receive = {
    case op: Operation =>
      println(s"Counter receive ${op}")
      persist(op) {
        op => updateState(op)
      }
    case "print" => println(s"The current state of couter is ${state}")
    case SaveSnapshotFailure(_, reason) => println(s"save snapshot failed, reason: ${reason}")
    case SaveSnapshotSuccess(_) => println(s"snapshot saved")
  }

  def updateState(op: Operation): Unit = op match {
    case Increment(n) =>
      state = state.inc(n)
      takeSnapshot
    case Decrement(n) =>
      state = state.dec(n)
      takeSnapshot
  }

  def takeSnapshot: Unit = {
    //    if (state % 5 == 0) saveSnapshot()
    saveSnapshot()
  }
}


object Counter {

  sealed trait Operation {
    val count: Int
  }

  case class Increment(override val count: Int) extends Operation

  case class Decrement(override val count: Int) extends Operation

  final case class State(n: Int) {
    def inc(x: Int) = State(n + x)

    def dec(x: Int) = State(n - x)
  }

}







object Persistent extends App {

  import Counter._

  val system = ActorSystem("persistent-actors")

  val counter = system.actorOf(Props[Counter])

  counter ! Increment(3)
  counter ! Increment(5)
  counter ! Decrement(3)
  counter ! "print"

  Thread.sleep(1000)

  system.terminate()

}

配置(application.conf):

akka {
  persistence {
    journal {
      plugin = "akka.persistence.journal.leveldb",
      leveldb {
        dir = "target/example/journal",
        native = false
      }
    },
    snapshot-store {
      plugin = "akka.persistence.snapshot-store.local",
      local {
        dir = "target/example/snapshots"
      }
    }
  }
}

运行应用程序两次显示状态根本不是持久性的:

Recovery completed.
Counter receive Increment(3)
Counter receive Increment(5)
Counter receive Decrement(3)
The current state of couter is State(5)
snapshot saved
snapshot saved
snapshot saved

Recovery completed.
Counter receive Increment(3)
Counter receive Increment(5)
Counter receive Decrement(3)
The current state of couter is State(5)
snapshot saved
snapshot saved
snapshot saved

为什么?

1 个答案:

答案 0 :(得分:3)

这里的问题是,您在演员收到的每个操作消息之后拍摄快照,但在拍摄快照时您没有保存其状态。如果你仔细看看你拍摄的快照代码:

def takeSnapshot: Unit = {
    //    if (state % 5 == 0) saveSnapshot()
    saveSnapshot()
  }

saveSnapshot()的调用不会拍摄您所在州的快照,因为没有传递任何参数。

您需要修改takeSnapshot方法,如下所示:

  def takeSnapshot: Unit = {
    //    if (state % 5 == 0) saveSnapshot()
    saveSnapshot(state) // Pass the states you need to store while taking a snapshot.
  }

这样可行。