Reputation: 5364
Is there any way I can convert a variable of type com.ning.http.client.ListenableFuture[A]
into a type scala.concurrent.Future[A]
in other words what would be the content of the function
def toFuture[A](a: com.ning.http.client.ListenableFuture[A]):scala.concurrent.Future[A] = ???
I am specifically in the case where A = com.ning.http.client.Response
Note that com.ning.http.client.ListenableFuture[A]
is not the same as com.google.common.util.concurrent.ListenableFuture
(and hence this proposed duplicate does not solve the issue)
Upvotes: 0
Views: 438
Reputation: 2900
The idea is the same as with guava's ListenableFuture
, although a little more constrained due to more constrained signature.
First, you need to get a java.util.concurrent.Executor
to add a callback. Since your Scala code interacts with a Java library, I'd suggest to define your pool of scala.concurrent.ExecutorService
s based on Java Executors - that way you can retain both the instance of an Executor and an ExecutorService, something like the following:
import java.util.concurrent.Executors
import scala.concurrent.ExecutionContext
val executor = Executors.newFixedThreadPool(5) // use it for Java futures
implicit val executionContext = ExecutionContext.fromExecutor(executor) // use it for Scala futures
The above steps are not needed if you want to process everything in different pools. In case you want to use an existing ExecutionContext
, here's a snippet I googled.
Then, to convert the ListenableFuture
into a Future
, I'd do something like this (considering some exception semantics of java.util.concurrent.Future
):
def toFuture[A](a: ListenableFuture[A]): Future[A] = {
val promise = Promise[A]()
a.addListener(new Runnable {
def run() = {
try {
promise.success(a.get)
} catch {
case ex: ExecutionException => promise.failure(ex.getCause)
case ex => promise.failure(ex)
}
}
}, executor)
promise.future
}
Upvotes: 1