Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ListenableFuture to scala Future

Tags:

scala

future

I am in the process of writing a small scala wrapper around a java library.

The java library has an object QueryExecutor exposing 2 methods:

  • execute(query): Result
  • asyncExecute(query): ListenableFuture[Result]

ListenableFuture in this context is the one from the guava library.

I want my scala wrapper to return a Future[Result] instead of the java object, but I am not sure what is the best way to implement that. Here are 2 solutions I came up with:

future {   executor.execute(query) } 

and

val p = promise[Result] val guavaFuture = executor.asyncExecute(query)  Futures.addCallback(guavaFuture, new FutureCallback[Result] {   def onFailure(t: Throwable) {     p.failure(t)   }    def onSuccess(result: Result) {     p.success(result)   } })  p.future 

I am wondering which method is the best. My intuition is that the first one, while returning a Future, will still block a thread while the call to execute waits for a response, the second one looks like it should be really non blocking. Any comment on the pros/cons of each method ?

like image 400
vptheron Avatar asked Aug 02 '13 21:08

vptheron


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 a Future in Scala?

A Future is a placeholder object for a value that may not yet exist. Generally, the value of the Future is supplied concurrently and can subsequently be used. Composing concurrent tasks in this way tends to result in faster, asynchronous, non-blocking parallel code.


1 Answers

The second option is best, it keeps everything asynchronous. but... you can do one better and abstract the solution into a reusable pattern:

implicit class RichListenableFuture[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   }     } 

You can then simply call:

executor.asyncExecute(query).asScala 
like image 50
Kevin Wright Avatar answered Sep 22 '22 08:09

Kevin Wright