Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are advantages of a Twitter Future over a Scala Future?

I know a lot of reasons for Scala Future to be better. Are there any reasons to use Twitter Future instead? Except the fact Finagle uses it.

like image 392
Sergey Alaev Avatar asked Oct 07 '15 08:10

Sergey Alaev


People also ask

What is the difference between a Java future and a Scala future?

A Java Future works in a synchronous blocking way. It does not work in an asynchronous non-blocking way, whereas a Scala Future works in an asynchronous non-blocking way. If we want an asynchronous non-blocking feature, we should use Java 8's CompletableFuture.

What is Scala future?

Future represents a result of an asynchronous computation that may or may not be available yet. When we create a new Future, Scala spawns a new thread and executes its code. Once the execution is finished, the result of the computation (value or exception) will be assigned to the Future.


2 Answers

Disclaimer: I worked at Twitter on the Future implementation. A little bit of context, we started our own implementation before Scala had a "good" implementation of Future.

Here're the features of Twitter's Future:

  • Some method names are different and Twitter's Future has some new helper methods in the companion.

e.g. Just one example: Future.join(f1, f2) can work on heterogeneous Future types.

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

o and i keep their types, they're not casted into the least common supertype Any.

  • A chain of onSuccess is guaranteed to be executed in order: e.g.:

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

#1 is guaranteed to be executed before #2

  • The Threading model is a little bit different. There's no notion of ExecutionContext, the Thread that set the value in a Promise (Mutable implementation of a Future) is the one executing all the computations in the future graph. e.g.:

    val f1 = new Promise[Int]
    f1.map(_ * 2).map(_ + 1)
    f1.setValue(2) // <- this thread also executes *2 and +1
    
  • There's a notion of interruption/cancellation. With Scala's Futures, the information only flows in one direction, with Twitter's Future, you can notify a producer of some information (not necessarily a cancellation). In practice, it's used in Finagle to propagate the cancellation of a RPC. Because Finagle also propagates the cancellation across the network and because Twitter has a huge fan out of requests, this actually saves lots of work.

    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"
    
  • Until recently, Twitter's Future were the only one to implement efficient tail recursion (i.e. you can have a recursive function that call itself without blowing up you call stack). It has been implemented in Scala 2.11+ (I believe).

like image 126
Steve Gury Avatar answered Oct 16 '22 12:10

Steve Gury


As far as I can tell the main difference that could go in favor of using Twitter's Future is that it can be cancelled, unlike scala's Future.

Also, there used to be some support for tracing the call chains (as you probably know plain stack traces are close to being useless when using Futures). In other words, you could take a Future and tell what chain of map/flatMap produced it. But the idea has been abandoned if I understand correctly.

like image 42
Régis Jean-Gilles Avatar answered Oct 16 '22 11:10

Régis Jean-Gilles