A functional Journey

by Rewati Raman
HTML5 Icon

Google Listenable Future To Scala Future

30 May 2017

A ListenableFuture in Guava allows you to register callbacks to be executed once the computation is complete, or if the computation is already complete, immediately. This simple addition makes it possible to efficiently support many operations that the basic Future interface cannot support. Technically ListenableFuture extends Future interface by adding simple method.

void addListener(Runnable listener, Executor executor)

But sometimes you may want to return a Future[Result] instead of the java object. I felt this need when I was trying to develop a very composable Spark data streaming pipeline. Also to leverage Scala language we need a object better than ListenableFuture. Ideally we can just convert to using Scala futures, but our supporting libraries are still returning ListenableFuture.

Here is an implicit conversion that can make life little easier.

implicit class GoogleListenableFutureToScalaFuture[T](lf: ListenableFuture[T]) {
    def asScala: Future[T] = {
      val p = Promise[T]()
      Futures.addCallback(lf, new FutureCallback[T] {
        def onFailure(t: Throwable): Unit = p failure t
        def onSuccess(result: T): Unit    = p success result
      })
      p.future
    }
  }

Now ListenableFuture can be conversted to Scala future by just using .asScala method.

val insertQuery = ...// Insert query 
val scalaFuture = session.executeAsync(insertQuery).asScala
scalaFuture.onComplete {
    case Failure(x: Exception) => {
     //handle exception
    }
    case _ => //handle success
}