加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – Actor和Future:引用onComplete中的actor消息

发布时间:2020-12-16 09:55:26 所属栏目:安全 来源:网络整理
导读:在重构其他程序员编写的actor代码时,我在actor A中遇到了Future.onComplete回调的使用,这违反了使用akka.pattern.pipe的最佳实践.这是一个坏主意,因为它暴露了竞争条件的可能性,因为Future实例可能在不同的线程上执行. 查看代码,我们看到在onComplete块中没
在重构其他程序员编写的actor代码时,我在actor A中遇到了Future.onComplete回调的使用,这违反了使用akka.pattern.pipe的最佳实践.这是一个坏主意,因为它暴露了竞争条件的可能性,因为Future实例可能在不同的线程上执行.

查看代码,我们看到在onComplete块中没有引用发送者和任何可变变量,因此它看起来非常安全,至少对于这个特定场合.然而,让我感到疑惑的一个灰色区域是对url的引用,尤其是文本.

是否有可能类似于Closing Over An Akka Actor Sender In The Receive问题,一个竞争条件发生,以至于在调用onComplete回调时,文本的值已经引用了不同的actor消息,导致所有的地狱崩溃?

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

解决方法

对文本的引用应该没问题.不同之处在于文本的每个“实例”都是绑定到当前匹配块范围的新变量(从案例文本开始…).因此,创造的未来恰好关闭了文本的价值.

这与发送者(或脱糖时的发送者())不同,后者实际上是在Actor特征上定义的方法,它返回由调用它的actor接收的最新消息的发送者的ActorRef,因此可以在稍后调用时(当最终调用Future的onComplete时)给出不同的值.

你也对使用onComplete感到怀疑.更好的选择是:

case text: String =>
  Future {
    fileUpload(text)
  } map { url => 
    Insert(url,text) 
  } pipeTo b

现在失败也将发送到b,而不是被悄悄吞下.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读