与 Scala Future 相比,Twitter Future 有哪些优势?
What are advantages of a Twitter Future over a Scala Future?
我知道很多让 Scala Future 变得更好的理由。有什么理由改用 Twitter Future 吗?除了 Finagle 使用它之外。
据我所知,支持使用 Twitter Future
的主要区别在于它可以取消,这与 Scala 的 Future
不同。
此外,过去曾有一些支持跟踪调用链(您可能知道,在使用 Futures 时,普通堆栈跟踪几乎毫无用处)。换句话说,您可以获取 Future 并告诉它是由 map
/flatMap
的哪个链产生的。但如果我理解正确的话,这个想法已经被放弃了。
免责声明:我曾在 Twitter 从事 Future 实施工作。一点上下文,我们在 Scala 有 Future
的 "good" 实现之前就开始了我们自己的实现。
这是 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)
}
o
和 i
保留它们的类型,它们不会被转换为最不常见的超类型 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
有一个概念interruption/cancellation。使用 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"
直到最近,Twitter 的 Future 是唯一实现高效尾递归的函数(即你可以有一个递归函数,它可以在不破坏调用堆栈的情况下调用自身)。它已在 Scala 2.11+ 中实现(我相信)。
我知道很多让 Scala Future 变得更好的理由。有什么理由改用 Twitter Future 吗?除了 Finagle 使用它之外。
据我所知,支持使用 Twitter Future
的主要区别在于它可以取消,这与 Scala 的 Future
不同。
此外,过去曾有一些支持跟踪调用链(您可能知道,在使用 Futures 时,普通堆栈跟踪几乎毫无用处)。换句话说,您可以获取 Future 并告诉它是由 map
/flatMap
的哪个链产生的。但如果我理解正确的话,这个想法已经被放弃了。
免责声明:我曾在 Twitter 从事 Future 实施工作。一点上下文,我们在 Scala 有 Future
的 "good" 实现之前就开始了我们自己的实现。
这是 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)
}
o
和 i
保留它们的类型,它们不会被转换为最不常见的超类型 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
有一个概念interruption/cancellation。使用 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"
直到最近,Twitter 的 Future 是唯一实现高效尾递归的函数(即你可以有一个递归函数,它可以在不破坏调用堆栈的情况下调用自身)。它已在 Scala 2.11+ 中实现(我相信)。