2016-10-16 29 views
2

我想使用ActorRef作为Map键。但是,由于Akka在发送消息时成为临时角色,因此我不能使用sender()作为密钥。使用Akka ActoRef作为Map键

反正有没有从邮件的发件人那里得到ActorRef

+0

从'sender'得到的'ActorRef'是一个新的actor(路径中的“tmp”),而不是消息的实际发送者。 – DennisVDB

+0

我在答案后的几天刚刚过来。有什么理由不接受它是正确的吗? – tkachuko

回答

2

让我们来看看这个。我会参考答案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 
    } 

此外请注意,发送者内部消息其在阿卡使用的属性。所以,除非您发送的邮件是这样的:

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

sender参数将提供阿卡本身:

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://[email protected]:5678/user/service-b" // remote 

所以,如果你的发件人可以从另一台主机的演员系统(远程情况下)你是完全好,因为正在使用的主机和端口名。现在到本地案例:akka确保您的路径独特在本地的演员系统内,这意味着将不会有同名的演员。

所以回答你的问题:是的,你可以存储发件人的结果()方法HashMap中作为重点。

希望它有帮助,先生!

+0

它有助于确保'sender()'可以用作关键字。然而,通过sender()收到的'ActorRef'与实际发送者的'ActorRef'不同。阿卡创建了一个临时演员。因此,我用_real_'ActorRefs'构造我的地图,这些键永远不会匹配。 – DennisVDB

+0

感谢您的评论。你能否指定以下事实的来源:“通过sender()接收的actorref与实际发送者的actorref不一样”。因为我在答案中基本证明了这是错误的陈述:)或者请解释你的意思。 – tkachuko

+0

最终的解决方案是简单地通过信息传递'self'',并且用您的答案我们知道我们可以安全地将它用作密钥。 – DennisVDB

相关问题