获取Akka询问的目标/接收者

xj3cbfub  于 2022-11-05  发布在  其他
关注(0)|答案(1)|浏览(179)

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

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

当我处理这个ask的成功响应时,那么发送者是self。我如何才能得到这个ask的响应的发送者?换句话说,我如何才能得到这里的目标/接收者参与者的地址?
编辑:
很明显,persistence是请求的目标。但我真正想知道的是,是否有一种方法可以通过pipeTo获得persistence地址。假设有一个persistence数组,那么我不知道哪个Persist消息来自哪个persistence

0s7z1bwu

0s7z1bwu1#

答案就在你的问题中。persistence是提问的目标。
有可能persistence正在将工作委托给另一个参与者(例如,池中的工作者),但这将揭示实现细节,并且tbh可能不会那么有用(这是为什么ask模式不传播sender的一部分)。
如果它是一个由您控制的协议,那么显式地向响应添加一个ActorRef就可以保证工作。
您可以使用自己的ask模式版本来传播发送者,尽管如上所述,它可能不会那么有用。
EDIT:要将persistence传播到转发的回复中,最简单的方法是将ask的Future结果map绑定到将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的元组,因此您可以在receive中将它们与以下内容匹配

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

(You还可以显式地将协议更改为包含ActorRef:元组可能有点太原始了,但是在不知道关于协议的更多细节的情况下,对于这个答案是方便的)
请注意,如果persistenceActor中的一个字段,那么在您发送请求和执行map/recoverWith之间,它可能会发生变化:map/recoverWith将最终获得更改后的值。这种无意中的“关闭”参与者状态是Akka中长期存在的严重错误的根源,因此可能值得使用

val persistenceTarget = persistence

以及用persistenceTarget替换在ask/map/recoverWith中对persistence的提及:由于persistenceTarget是一个本地(且不可变)值,因此关闭它是安全的。

相关问题