2016-06-03 15 views
0

Gibt es eine Möglichkeit, com.ning.http.client.ListenableFuture[A] in einen Typ eine Variable vom Typ umwandeln kann scala.concurrent.Future[A]convert `com.ning.http.client.ListenableFuture [Alles]` `in scala.concurrent.Future [Alles]`

in mit anderen Worten, was der Inhalt der Funktion

def toFuture[A](a: com.ning.http.client.ListenableFuture[A]):scala.concurrent.Future[A] = ??? 

ich bin speziell, wo A = com.ning.http.client.Response

Hinweis im Fall wäre, dass com.ning.http.client.ListenableFuture[A] ist nicht das gleiche wie com.google.common.util.concurrent.ListenableFuture (und damit this proposed duplicate löst das Problem nicht)

Antwort

1

Die Idee ist die gleiche wie mit Guavas ListenableFuture, obwohl ein wenig eingeschränkter aufgrund der eingeschränkteren Signatur.

Zuerst müssen Sie eine java.util.concurrent.Executor erhalten, um einen Rückruf hinzuzufügen. Da Ihr Scala-Code mit einer Java-Bibliothek interagiert, würde ich vorschlagen, Ihren Pool von scala.concurrent.ExecutorService s basierend auf Java Executors zu definieren - auf diese Weise können Sie sowohl die Instanz eines Executors als auch einen ExecutorService in etwa wie folgt beibehalten:

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 

Die obigen Schritte sind nicht erforderlich, wenn Sie alles in verschiedenen Pools verarbeiten möchten. Wenn Sie eine bestehende ExecutionContext verwenden möchten, hier ist eine snippet ich googelte.

Dann die ListenableFuture in eine Future zu konvertieren, ich so etwas tun würde (einige Ausnahme Semantik von java.util.concurrent.Future bedenkt):

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 
} 
+0

Vielen Dank für Ihre Antwort !, ich 'Objekterstellung unmöglich, da Methode run in trait Runnable vom Typ() Unit ist nicht definiert 'keine Idee? – John

+0

toll, danke, kompiliert jetzt – John