【发布时间】:2015-10-13 05:16:51
【问题描述】:
在重构其他一些程序员编写的actor代码时,我遇到了在actorA中使用Future.onComplete回调,这违背了使用akka.pattern.pipe的最佳实践。这是一个坏主意,因为它暴露了竞争条件的可能性,因为 Future 实例可能在不同的线程上执行。
查看代码,我们看到在 onComplete 块中既没有 sender 也没有任何可变的 vars 被引用,所以它看起来很安全,至少对于 这个特定的场合。然而,让我感到疑惑的一个灰色区域是对url 的引用,尤其是text。
是否有可能类似于Closing Over An Akka Actor Sender In The Receive 问题,发生竞争条件,使得在调用onComplete 回调时,text 的值已经引用了不同的参与者消息,导致所有地狱挣脱?
class B extends akka.actor.Actor {
def receive = {
case urlAndText: (String, String) => // do something
}
}
class A extends akka.actor.Actor {
case class Insert(url: String)
def fileUpload(content: String): String = ??? // returns the url of the uploaded content
val b = context.actorOf(Props(classOf[B]))
def receive = {
case text: String =>
Future {
fileUpload(text)
} onComplete {
case Success(url) =>
b ! Insert(url, text) // will this be
}
}
}
【问题讨论】: