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:
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 ?
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With