Akka:两个演员之间同步状态的正确模式

时间:2017-07-27 14:07:38

标签: synchronization akka persistence actor akka-persistence

在重写Akka中已弃用的persistentView的过程中,我有一个需要对其状态进行快照的读取actor,并且到目前为止读取了日志事件偏移量。要停止需要序列化复合数据结构的视图actor(状态+偏移量),我将偏移值快照的责任委托给子actor。然后问题是同步这两者之间的偏移值。目前在阅读演员中,我有:

case RecoveryCompleted ⇒
  implicit val ec = context.dispatcher
  val lastSequenceNr = (sequenceSnapshotterRef ? GetLastSnapshottedSequenceNr).mapTo[QueryOffset]
  lastSequenceNr onComplete {
    case Success(QueryOffset(sequenceNr)) ⇒
      offsetForNextFetch = sequenceNr
      doSomethingBasedOnThecompositeData()
      ...

并且要更新子actor的偏移值以便同步快照,我这样做:

case RequestSnapshot ⇒
  implicit val ec = context.dispatcher
  val offsetUpdated = sequenceSnapshotterRef ? 
QueryViewSequenceApi.UpdateSequenceNr(offsetForNextFetch)

  offsetUpdated map {
    _ ⇒
      saveSnapshot()
      snapshotRequested = false
  } recover{
    case _ ⇒
      self ! RequestSnapshot
      log.debug("QueryViewSequenceSnapshotter not reachable. Will try again.")
  }
}

然而,这意味着如果儿童演员的确认丢失或者儿童演员在发送消息之前死亡,然后视图演员在等待来自儿童演员的offsetUpdated响应时死亡,则偏移当父母试图恢复时,状态将处于未同步状态。

  • 这个案子是否值得担心?当一个本地儿童演员如果只是像我的孩子演员那样简单地进行简单算术时,会不会随意死亡?
  • 如何修改设计以确保可以处理?我可能会在双方都引入一个确认,并在双方引入两阶段同步机制,但这可能是错误的。

以下是问题的完整context

更新:在message delivery reliability上阅读更多内容,我意识到这是一个更普遍的问题。我可以配置此父级和参与者使用at-least-once传递机制,而我的项目的其余部分使用默认的at-most-once传递机制吗?在尝试将确认消息发送回父母之前,仍然无法解决儿童演员死亡的问题。

1 个答案:

答案 0 :(得分:0)

我建议您使用持久性保证请求以及Akka的死亡监视。它仍然不平凡:仍然存在许多漏洞。

Akka也有一次保证,但总的来说,我该怎么做:取消请求直到确认完成。定期告诉,我将状态保持在发送者中。超时由调度程序处理。

如果孩子死了,对终结者做出反应,然后继续循环。