事件没有在Akka 2.4.0 Persistence& amp; Cassandra Journal插件0.6

时间:2016-03-25 15:39:34

标签: cassandra akka akka-persistence

我尝试使用Akka(版本2.4.0)Persistency和Cassandra Plugin(版本0.6,https://github.com/krasserm/akka-persistence-cassandra)编写应用程序以从故障中恢复。 事件被存储到cassandra没有问题,但是,我试图杀死和演员,所以主管重新启动它,receiveRecover没有收到事件。

似乎问题在于插件本身,就好像我使用共享的LevelDB而不是cassandra一样,事件正在恢复步骤中接收。

这是我的持久性演员的实现:



    class SimplePersistentActor extends PersistentActor with ActorLogging {

      def persistenceId: String = context.self.path.name

      override def preRestart(cause: Throwable, msg: Option[Any]) = {
        log.debug(s"Restarting ${getClass.getSimpleName}")
        super.preRestart(cause, msg)
      }

      override def postStop() = {
        log.debug(s"Stopping ${getClass.getSimpleName}")
        super.postStop()
      }

      var transactionData: Either[UninitializedData, RunningTransactionData] = Left(UninitializedData())

      def receiveCommand ={
        case msg @ TransactionStart(transactionId) =>
          persist(msg) { _ => }
          log.debug(s"Starting a transaction with id $transactionId")
          transactionData = Right(RunningTransactionData(transactionId, List()))

          /* Send a reply */
          sender() ! transactionId

        case msg @ TransactionData(data) =>
          persist(msg) { _ => }

          transactionData match {
            case Right(t: RunningTransactionData) =>
              val updatedTransaction = t.copy(data = t.data ::: List(data))
              log.debug(s"There are ${updatedTransaction.data.size} data items within a transaction ${t.transactionId}")
              transactionData = Right(updatedTransaction)

              /* Send a reply */
              sender() ! t.transactionId          

            case _ => log.error("Actor's transaction data is not initialized")
          }

        case TransactionEnd(transactionId) =>
          transactionData match {
            case Right(t: RunningTransactionData) =>
              log.debug(s"Ending a transaction with id ${t.transactionId}")
              transactionData = Left(UninitializedData())

              /* Send a reply */
              sender() ! t.transactionId

            case _ => log.error("Actor's transaction data is not initialized")
          }      

        case other =>
          log.debug(s"Unexpected event received: $other")
      }

      def receiveRecover = {
        case message =>
          log.debug(s"Recovery Step. Message $message received")
      }
    }


在上面描述的两种情况下,代码都没有改变。 有没有人见过这个问题?

1 个答案:

答案 0 :(得分:0)

我遇到了同样的事情,并找到了适合我的修复程序。我知道您的问题已经很老了,但是由于我在最新版本的Akka Cassandra Persistence(0.86)上看到了同样的问题,因此我认为值得一提。

我遇到的问题来自以下配置。

cassandra-main-journal = ${cassandra-journal} {
  contact-points = ["localhost"]
  keyspace-autocreate = true
  tables-autocreate = true
  keyspace = "main_akka_journal"
}

因此,采用默认的cassandra-journal配置并覆盖keyspace。然后,就像您在做的那样,在Akka持久性actor中覆盖persistenceId以指向此配置。

如果执行此操作,将所有对Actor的写入都转到main_akka_journal键空间。重新启动Actor时,您会收到一条RecoveryCompleted消息,但是看不到您编写的任何消息。但是,当您收到RecoveryCompleted时,lastSequenceNr将是正确的。

有趣的是,如果您拥有keyspace-autocreate=true,则会在创建的地方看到两个键空间。 main_akka_journalakka

所以问题是持久性参与者正在写入main_akka_journal密钥空间,重新启动时它是从akka密钥空间(为空)中读取事件,然后从lastSequenceNr中读取事件。 main_akka_journal键空间(正确)。

对我来说,解决方案是此配置:

cassandra-main-journal = ${cassandra-journal} {
  contact-points = ["localhost"]
  keyspace-autocreate = true
  tables-autocreate = true
  keyspace = "main_akka_journal"
  query-plugin = "cassandra-main-query-plugin"
}

cassandra-main-query-plugin = ${cassandra-query-journal} {
  write-plugin = "cassandra-main-journal"
}

否则默认情况下,write-plugin指向cassandra-journalakka键空间。