Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala.concurrent.Future wrapper for java.util.concurrent.Future

I'm using Play Framework 2.1.1 with an external java library that produces a java.util.concurrent.Future result. I'm using the scala future's as opposed to Akka which I think is the right thing to do as of Play 2.1. How can I wrap the java.util.concurrent.Future up into a scala.concurrent.Future while still keeping the code non-blocking?

def geConnection() : Connection = {
  // blocking with get
  connectionPool.getConnectionAsync().get(30000, TimeUnit.MILLISECONDS)
}

The above code returns a connection but uses a get so it becomes blocking

def getConnectionFuture() : Future[Connection] = {
  future {
    // how to remove blocking get and return a scala future?
    connectionPool.getConnectionAsync().get(30000, TimeUnit.MILLISECONDS)
  }
}

Ideally I want a scala function that returns the connection as a future like the code above but without the code blocking via the get. What else do I need to put into the function to make it non blocking.

Any pointers would be great.

like image 916
Mark Sivill Avatar asked Jun 20 '13 13:06

Mark Sivill


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 Java Util Concurrent Future?

util. concurrent. Future , represents the result of an asynchronous computation. When the asynchronous task is created, a Java Future object is returned. This Future object functions as a handle to the result of the asynchronous task.

What is a 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.

What is ExecutionContext Scala?

An ExecutionContext can execute program logic asynchronously, typically but not necessarily on a thread pool. A general purpose ExecutionContext must be asynchronous in executing any Runnable that is passed into its execute -method.


3 Answers

import java.util.concurrent.{Future => JFuture} import scala.concurrent.{Future => SFuture} 

You can't wrap JFuture with SFuture without blocking since there is a callback in SFuture (onComplete) and there is only blocking get in JFuture.

All you can do is to create additional thread and block it with get, then complete Promise with result of get.

val jfuture: JFuture[T] = ??? val promise = Promise[T]() new Thread(new Runnable { def run() { promise.complete(Try{ jfuture.get }) }}).start val future = promise.future 

You could check isDone in endless loop, but I don't think it is better then blocking.

like image 187
senia Avatar answered Oct 06 '22 04:10

senia


Future {
  blocking {
    jfuture.get
  }
}

This lets the ExecutionContext know that what you are doing is going to block, giving it a chance to allocate more threads. If you do not include blocking { } then you may run out of threads.

like image 39
Dr.Haribo Avatar answered Oct 06 '22 03:10

Dr.Haribo


     import java.util.concurrent.{Future => JFuture}
     import scala.concurrent.ExecutionContext.Implicits.global
     import scala.concurrent.Future
     import scala.util.Try

     object JFuture2SFuture {
        val jFuture: JFuture[Int] = ???
        val promise = Promise[Int]()
        Future { promise.complete(Try(jFuture.get)) } //it is non blocking 
        val sFuture:Future[Int] = promise.future

     }
like image 23
Sky Avatar answered Oct 06 '22 04:10

Sky