2013-02-05 14 views
5

Piszę program zakończenia serwera za pomocą Twittera Finlipsa. Nie używam pełnego stosu serwerów Twitter, tylko część, która umożliwia przetwarzanie asynchroniczne (tak Future, Function, itp.). Chcę przyszłości obiekty mają limity czasu, więc napisałem tak:Czas przyszły na Twitter nie dotyczy całego łańcucha FlatMap

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

time_consuming_function1 trwa dłużej niż 5 sekund. Ale future nie traci czasu po 5 sekundach i czeka aż time_consuming_function1 skończy.

Myślę, że to dlatego, że future.get(timeout) dba tylko o to, jak długo trwa tworzenie future, a nie o cały łańcuch operacji. Czy istnieje sposób na przekroczenie limitu czasu całego łańcucha operacji?

+0

Dzięki sschaef za edytowanie – stackoverflower

+0

Czy moja odpowiedź jest niewystarczająca? –

Odpowiedz

1

Zasadniczo, jeśli wywołasz mapę/płaską mapę w zadowolonej przyszłości, kod zostanie natychmiast wykonany.

W twoim przykładzie satysfakcjonujesz swoją przyszłość natychmiast po wywołaniu Future.value(some_input), więc flatMap natychmiast wykonuje kod, a połączenie z get nie musi czekać na nic. Ponadto wszystko dzieje się w jednym wątku. Bardziej odpowiednie byłoby to:

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