2013-02-05 4 views
5

Ich schreibe ein Server-Endprogramm mit Twitter Finagle. Ich benutze nicht den vollen Twitter-Server-Stack, sondern nur den Teil, der asynchrone Verarbeitung ermöglicht (also Future, Function, etc). Ich möchte die Zukunft Objekte Timeouts haben, so dass ich dies schrieb:Twitter Future Timeout gilt nicht für die gesamte flatMap-Kette

Future<String> future = Future.value(some_input).flatMap(time_consuming_function1); 
future.get(Duration.apply(5, TimeUnit.SECONDS)); 

time_consuming_function1 läuft länger als 5 Sekunden. Aber future nicht nach 5 Sekunden Timeout und es wartet, bis time_consuming_function1 fertig ist.

Ich denke, das ist, weil future.get(timeout) nur daran interessiert ist, wie lange die future dauerte, um zu erstellen, nicht die gesamte Operationskette. Gibt es eine Möglichkeit, die gesamte Operationskette zu unterbrechen?

+0

Danke sschaef zum Bearbeiten – stackoverflower

+0

Ist meine Antwort unzureichend? –

Antwort

1

Grundsätzlich, wenn Sie map/flatMap auf eine zufriedene Zukunft aufrufen, wird der Code sofort ausgeführt.

In Ihrem Beispiel erfüllen Sie sofort Ihre Zukunft, wenn Sie Future.value(some_input) anrufen, also führt flatMap den Code sofort aus und der Anruf an get muss nicht auf irgendetwas warten. Außerdem geschieht alles in einem Thread. Eine geeignetere Verwendung wäre wie folgt:

import scala.concurrent.ops._ 
import com.twitter.conversions.time._ 
import com.twitter.util.{Future,Promise} 

val p = new Promise[String] 
val longOp = (s: String) => { 
    val p = new Promise[String] 
    spawn { Thread.sleep(5000); p.setValue("Received: " + s) } 
    p 
} 
val both = p flatMap longOp 
both.get(1 second) // p is not complete, so longOp hasn't been called yet, so this will fail 
p.setValue("test") // we set p, but we have to wait for longOp to complete 
both.get(1 second) // this fails because longOp isn't done 
both.get(5 seconds) // this will succeed 
Verwandte Themen