【问题标题】:What are advantages of a Twitter Future over a Scala Future?Twitter Future 与 Scala Future 相比有哪些优势?
【发布时间】:2016-01-04 10:14:28
【问题描述】:

我知道 Scala Future 变得更好的很多原因。有什么理由改用 Twitter Future 吗?除了 Finagle 使用它的事实。

【问题讨论】:

    标签: scala twitter finagle twitter-finagle twitter-util


    【解决方案1】:

    免责声明:我曾在 Twitter 从事 Future 的实施工作。稍微了解一下,我们在 Scala 有一个“好的”Future 实现之前就开始了自己的实现。

    以下是 Twitter 的 Future 的功能:

    • 一些方法名称不同,Twitter 的 Future 在伴随程序中有一些新的辅助方法。

    例如仅举一个例子:Future.join(f1, f2) 可以处理异构的 Future 类型。

    Future.join(
      Future.value(new Object), Future.value(1)
    ).map {
      case (o: Object, i: Int) => println(o, i)
    }
    

    oi 保留它们的类型,它们不会被转换为最不常见的超类型 Any

    • onSuccess 链保证按顺序执行: 例如:

      f.onSuccess { 
        println(1) // #1
      } onSuccess { 
        println(2) // #2
      }
      

    #1 保证在 #2 之前执行

    • 线程模型有点不同。没有 ExecutionContext 的概念,在 Promise(未来的可变实现)中设置值的线程是执行未来图中所有计算的线程。 例如:

      val f1 = new Promise[Int]
      f1.map(_ * 2).map(_ + 1)
      f1.setValue(2) // <- this thread also executes *2 and +1
      
    • 有一个中断/取消的概念。使用 Scala 的 Futures,信息只向一个方向流动,使用 Twitter 的 Future,您可以通知生产者一些信息(不一定是取消)。在实践中,它在 Finagle 中用于传播 RPC 的取消。因为 Finagle 还会通过网络传播取消,而且 Twitter 拥有大量请求,这实际上节省了很多工作。

      class MyMessage extends Exception
      
      val p = new Promise[Int]
      p.setInterruptHandler {
        case ex: MyMessage => println("Receive MyMessage")
      }
      
      val f = p.map(_ + 1).map(_ * 2)
      f.raise(new MyMessage) // print "Receive MyMessage"
      
    • 1234563它已在 Scala 2.11+ 中实现(我相信)。

    【讨论】:

    • 取消是有道理的,尤其是当您发出重复请求以对抗延迟时...
    • 你好,史蒂夫。好久不见:-D。希望你一切都好。关于这个问题,线程模型的部分确实是一个巨大的差异,我忘记了那个。使用 scala 的Future,我们必须在每次只想映射未来时请求一个隐式执行上下文,即使是添加日志等琐碎的事情,而使用 Twitter 的 Future,我们可以搭载原始未来的线程。跨度>
    • 好吧,我不知道为什么 Scala 不提供像 Twitter 的 LocalScheduler 一样工作的 ExecutionContext。
    【解决方案2】:

    据我所知,支持使用 Twitter 的 Future 的主要区别在于它可以被取消,这与 scala 的 Future 不同。

    此外,曾经有一些对跟踪调用链的支持(您可能知道在使用 Futures 时,普通的堆栈跟踪几乎是无用的)。换句话说,您可以使用 Future 并告诉 map/flatMap 的哪个链产生了它。但是如果我理解正确的话,这个想法已经被放弃了。

    【讨论】:

    • 是的,但他们不久前弃用了 cancel(),转而支持不那么强制性的 raise()。你在生产代码中使用了 cancel() 吗?有用吗?
    • 我没有使用它,部分原因是我不想被非标准 Twitter 的Future 卡住。但很容易看出它的用途。假设您同时生成几个期货,然后通过Future.sequence 加入它们的结果以构建最终结果。如果任何一个失败,您希望快速失败,换句话说,取消所有其他期货,以使自己免于无用的计算。可以说,处理这种情况(不依赖于未来的取消)的标准/更好/不那么脆弱的方法是使用演员来代替。
    • 至于 cancel 被弃用以支持 raise,理由仍然成立:这不是 scala 的 Future可能 让你达到Twitter 的版本。
    • @RégisJean-Gilles 顺便说一句,“如果有人失败,你想快速失败”——这对于标准 Future.sequence 来说不是问题,因为它直到所有序列中的Futures 完成,即使其中一些提前失败。
    • "直到序列中的所有 Future 都完成后才会完成,即使其中一些提前失败。"我是说,有时您不仅希望在其中一个输入未来失败时完成(失败)最终未来,而且还希望在任何一个已经失败时立即停止所有未来的执行。 Future.sequence当然不会那样做。
    猜你喜欢
    • 2015-07-30
    • 2013-09-22
    • 2012-05-17
    • 1970-01-01
    • 2011-08-02
    • 2011-03-26
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    相关资源
    最近更新 更多