play framework java scala concurrency playframework-2.1 future

framework - scala.concurrent.Future wrapper para java.util.concurrent.Future



play framework return file (4)

Estoy usando Play Framework 2.1.1 con una biblioteca java externa que produce un resultado java.util.concurrent.Future. Estoy usando el futuro de Scala en lugar de Akka, que creo que es lo correcto en Play 2.1. ¿Cómo puedo envolver el java.util.concurrent.Future en un scala.concurrent.Future mientras mantengo el código sin bloquear?

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

El código anterior devuelve una conexión pero utiliza un get para que se bloquee.

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

Idealmente, quiero una función de scala que devuelva la conexión como un futuro como el código anterior pero sin el bloqueo de código a través de la obtención. ¿Qué más necesito poner en la función para que no se bloquee?

Cualquier punto sería genial.



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

No puedes envolver JFuture con SFuture sin bloquear, ya que hay una devolución de llamada en SFuture ( onComplete ) y solo hay bloqueo para get JFuture .

Todo lo que puedes hacer es crear un hilo adicional y bloquearlo con get , luego completar Promise con el resultado de 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

Podrías comprobar isDone en un bucle sin fin, pero no creo que sea mejor que bloquear.


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 }


Future { blocking { jfuture.get } }

Esto le permite al ExecutionContext saber que lo que está haciendo va a bloquear, lo que le da la oportunidad de asignar más subprocesos. Si no incluye el blocking { } , puede quedarse sin hilos.