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

斯卡拉 – 承诺有缺陷吗?

发布时间:2020-12-16 18:31:32 所属栏目:安全 来源:网络整理
导读:就像 this question的作者一样,我试图理解Scala 2.10期货和承诺中用户可见承诺的推理. 特别是,再次到example from the SIP,是不是完全有缺陷: import scala.concurrent.{ future,promise }val p = promise[T]val f = p.futureval producer = future { val r
就像 this question的作者一样,我试图理解Scala 2.10期货和承诺中用户可见承诺的推理.

特别是,再次到example from the SIP,是不是完全有缺陷:

import scala.concurrent.{ future,promise }
val p = promise[T]
val f = p.future
val producer = future {
  val r = produceSomething()
  p success r
  continueDoingSomethingUnrelated()
}
val consumer = future {
  startDoingSomething()
  f onSuccess {
    case r => doSomethingWithResult()
  }
}

我想象的是,对produceSomething的调用会导致运行时异常.因为承诺和生产者 – 未来是完全分离的,这意味着系统挂起,消费者永远不会成功或失败.

因此,使用promises的唯一安全方法需要类似的东西

val producer = future {
  try {
    val r.produceSomething()
    p success r
  } catch {
     case e: Throwable =>
       p failure e
       throw e  // ouch
  }
  continueDoingSomethingUnrelated()
}

这显然容易出错并且冗长.

我可以看到唯一一个可见的承诺类型 – 未来{}不足的情况 – 是M. A. D.答案中的回调挂钩之一.但SIP的例子对我来说没有意义.

解决方法

组合子

您可以使用Promise构建库中尚未包含的其他Future组合器.

>“选择”关闭第一个未来.返回结果,剩余的期货作为序列:https://gist.github.com/viktorklang/4488970.
>返回在一段时间后完成的Future的after方法,以“超时”Future:https://gist.github.com/3804710.

你需要Promises才能创建像这样的其他组合器.

适应回调

使用Promise使基于回调的API适应基于Future的API.例如:

def retrieveThing(key: String): Future[Thing] = {
  val p = Promise[Thing]()

  val callback = new Callback() {
    def receive(message: ThingMessage) {
      message.getPayload match {
        case t: Thing =>
          p success t        
        case err: SystemErrorPayload =>
          p failure new Exception(err.getMessage)
      }
    }
  }

  thingLoader.load(key,callback,timeout)
  p.future
}

同步器

使用Promise构建同步器.例如,为昂贵的操作返回缓存值,或者计算它,但不要为同一个键计算两次:

private val cache = new ConcurrentHashMap[String,Promise[T]]

def getEntry(key: String): Future[T] = {
  val newPromise = Promise[T]()
  val foundPromise = cache putIfAbsent (key,newPromise)

  if (foundPromise == null) {
    newPromise completeWith getExpensive(key)
    newPromise.future
  } else {
    foundPromise.future
  }
}

(编辑:李大同)

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

    推荐文章
      热点阅读