获取 target/recipient 的 Akka 问

Get target/recipient of Akka ask

我在我的 Akka 经典项目中使用了以下代码片段。

(persistence ? Persist("a", Some(100), 123)) (100.milliseconds)
  .mapTo[Persisted]
  .recover(ex => Failure(ex.getMessage()))
  .pipeTo(self)

当我处理这个 ask 的成功响应时,发件人是 self。如何获得对此 ask 的回复的发件人?换句话说,我怎样才能在这里得到目标/接收演员的地址?

编辑:

很明显 persistence 是询问的目标。但我真正想知道的是,是否有办法让 persistence 地址通过 pipeTo 可用。假设有一个 persistence 的数组,我不知道哪个 Persist 消息来自哪个 persistence.

答案就在你的问题中。 persistence 是提问的目标。

有可能 persistence 将工作委派给另一个参与者(例如池中的工作人员),但这会揭示实施细节,而且 tbh 可能不会那么有用(这是为什么的一部分询问模式不会传播发件人)。

如果它是您控制的协议,明确地向响应添加 ActorRef 保证有效。

您可以推出您自己的传播发件人的询问模式版本,尽管如上所述,它可能不会那么有用。

编辑:要将 persistence 传播到转发的回复中,最简单的方法是将 mapFuture 结果与结果捆绑在一起 persistence (作为一种相关 ID),如:

(persistence ? Persist("a", Some(100), 123)) (100.milliseconds)
  .mapTo[Persisted]
  .map { response => persistence -> response }
  .recoverWith { ex => persistence -> Failure(ex.getMessage) }
  .pipeTo(self)

发送的消息将是 ActorRefPersistedFailure 的元组,因此您可以在接收中将它们与

case (persistenceTarget, Persisted(...)) => ???
case (persistenceTarget, Failure(msg)) => ???

(您也可以将协议显式更改为包含 ActorRef 的内容:元组可能有点过于原始,但在不知道有关协议的更多详细信息的情况下对于此答案很方便)

请注意,如果 persistence 是您 Actor 中的一个字段,它可能会在您发送请求和执行 map/recoverWith 之间发生变化: map/recoverWith 将最终选择更改后的值。这种无意的“关闭”actor 状态是 Akka 中长期存在的讨厌错误的来源,因此可能值得

val persistenceTarget = persistence

并用 persistenceTarget 替换 ask/map/recoverWith 中提及的 persistence:因为 persistenceTarget 是本地(且不可变的)值, 关闭就安全了。