Akka classic项目中ask模式下如何通过pipeTo获取目标actor地址
问题根因
Akka的?(ask)操作符会生成一个临时代理Actor用于接收应答,你调用pipeTo(self)时,Future结果的传递已经脱离了目标persistence Actor的上下文,所以你收到消息时sender()默认就是当前Actor自己,天然不携带原始目标Actor的引用。
最优解决方案
直接在Future转换阶段把目标persistence Actor的引用和应答结果绑定即可,完美适配多persistence Actor的场景:
- 首先定义携带源Actor标识的消息体:
// 成功应答携带源Actor case class PersistedWithSource(persisted: Persisted, sourcePersistence: ActorRef) // 失败应答同样携带源Actor case class PersistFailedWithSource(errorMsg: String, sourcePersistence: ActorRef)
- 修改原ask逻辑,绑定Actor引用:
// 遍历persistence数组场景示例 persistenceList.foreach { persistenceActor => (persistenceActor ? Persist("a", Some(100), 123))(100.milliseconds) .mapTo[Persisted] .map(res => PersistedWithSource(res, persistenceActor)) .recover(ex => PersistFailedWithSource(ex.getMessage, persistenceActor)) .pipeTo(self) }
- 接收消息时直接匹配即可区分不同的源persistence Actor:
def receive: Receive = { case PersistedWithSource(persisted, source) => // 这里source就是你要的目标persistence Actor地址,直接用即可 println(s"收到来自${source.path}的持久化成功应答:$persisted") case PersistFailedWithSource(err, source) => println(s"收到来自${source.path}的持久化失败应答,错误:$err") }
这个方案没有额外性能损耗,是Akka官方推荐的多Actor请求应答区分的标准实现方式。
内容的提问来源于stack exchange,提问作者dhaliman
相关产品推荐
相关产品推荐

