使用Akka ActoRef作为Map键

时间:2016-10-16 22:04:07

标签: scala hashmap akka

我想将ActorRef用作Map密钥。但是,由于Akka在发送邮件时会成为临时演员,因此我无法使用sender()作为密钥。

无论如何都要从邮件的发件人那里获取真实的 ActorRef吗?

1 个答案:

答案 0 :(得分:2)

让我们来看看这个。我将在这个答案中引用akka 2.4.2 来源。

sender()方法实现如下:

  final def sender(): ActorRef = currentMessage match {
    case null                      ⇒ system.deadLetters
    case msg if msg.sender ne null ⇒ msg.sender
    case _                         ⇒ system.deadLetters
  }

此外请注意发件人是内部消息的属性,用于akka。所以,除非你发送这样的信息:

self.tell("no sender here", null)
self ! ("no sender here", null)

sender参数将由akka本身提供:

  final def tell(msg: Any, sender: ActorRef): Unit = this.!(msg)(sender)

现在,唯一需要回答的问题是equals()hashCode()方法的实施,以确保ActorRef可以存储HashMap

  final override def hashCode: Int = {
    if (path.uid == ActorCell.undefinedUid) path.hashCode
    else path.uid
  }

  final override def equals(that: Any): Boolean = that match {
    case other: ActorRef ⇒ path.uid == other.path.uid && path == other.path
    case _               ⇒ false
  }

因此,您可以看到equalshashCode几乎不依赖于演员的路径。现在什么是演员路径:

"akka://my-sys/user/service-a/worker1"                   // purely local
"akka.tcp://my-sys@host.example.com:5678/user/service-b" // remote

因此,如果您的发件人可以来自其他主机的演员系统(远程案例),那么您完全没问题,因为正在使用主机和端口名称。现在转到本地案例:akka确保您的路径在本地actor系统中唯一,这意味着不会有任何具有相同名称的actor。

回答您的问题:是的,您可以将发送方()方法的结果存储在 HashMap 中作为密钥。

希望它有所帮助,先生!