Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 参与者和未来:指onComplete中的参与者消息_Scala_Akka_Future - Fatal编程技术网

Scala 参与者和未来:指onComplete中的参与者消息

Scala 参与者和未来:指onComplete中的参与者消息,scala,akka,future,Scala,Akka,Future,在重构其他程序员编写的actor代码时,我遇到了在actorA中使用Future.onComplete回调的情况,这与使用akka.pattern.pipe的最佳实践背道而驰。这是一个坏主意,因为它暴露了竞争条件的可能性,因为未来的实例可能会在不同的线程上执行 查看代码,我们发现在onComplete块中既没有sender也没有任何可变的vars被引用,因此它看起来相当安全,至少在这个特定的场合是如此。然而,有一个灰色区域让我感到疑惑,那就是对url的引用,尤其是对text的引用 与问题类似,是

在重构其他程序员编写的actor代码时,我遇到了在actor
A
中使用
Future.onComplete
回调的情况,这与使用
akka.pattern.pipe
的最佳实践背道而驰。这是一个坏主意,因为它暴露了竞争条件的可能性,因为
未来的
实例可能会在不同的线程上执行

查看代码,我们发现在
onComplete
块中既没有
sender
也没有任何可变的
var
s被引用,因此它看起来相当安全,至少在这个特定的场合是如此。然而,有一个灰色区域让我感到疑惑,那就是对
url
的引用,尤其是对
text
的引用

与问题类似,是否可能发生竞态条件,即在调用
onComplete
回调时,
text
的值已经引用了不同的参与者消息,从而导致所有hell崩溃

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
      }
  }
}

在这种情况下,您将不会遇到任何竞争条件,尽管正如您所指出的,通常以这种方式构造代码不是一个特别好的主意

url
text
的引用都很好。
url
的值只是一个成功完成的未来的提取,它不会改变你是否是演员。
text
的值是一个不可变的字符串,在将来关闭该值不会导致问题,因为该字符串实例是不可变的


正如您所指出的,关闭发送方或var是一个问题,这是因为作为可变对象,这些值在未来完成时可能会发生变化,而不可变值即使在关闭它们时也会保持不变。

文本的引用应该可以。区别在于
文本的每个“实例”都是绑定到当前匹配块范围的新变量(从
案例文本开始…
)。因此,所创建的
未来
文本
的值很接近

这与
sender
(或
sender()
脱糖时)不同,后者实际上是在
Actor
特征上定义的一种方法,它返回被调用的Actor最近收到的消息的发送者的
ActorRef
,因此在以后调用时可以给出不同的值(当最后调用
Future
onComplete
时)

您对使用
onComplete
的怀疑也是正确的。更好的选择是:

case text: String =>
  Future {
    fileUpload(text)
  } map { url => 
    Insert(url, text) 
  } pipeTo b
现在,故障也将被发送到
b
,而不是被悄悄地吞没