2016-10-10 5 views
1

Ich schreibe gerade Codes, um das Future-Companion-Objekt zu erweitern. Eine Funktion, die ich umsetzen will, ist AnySeltsames Verhalten von Scala Future und Thread.sleep

//returns the future that computes the first value computed from the list. If the first one fails, fail. 
def any[T](fs: List[Future[T]]): Future[T] = { 
    val p = Promise[T]() 

    fs foreach { f => { 
    f onComplete { 
     case Success(v) => p trySuccess v 
     case Failure(e) => p tryFailure e 
    } 
    } } 

    p.future 
} 

Ich habe versucht, meinen Code zu testen, mit

test("A list of Futures return only the first computed value") { 
    val nums = (0 until 10).toList 
    val futures = 
     nums map { n => Future { Thread.sleep(n*1000); n } } 

    val v = Await.result(Future.any(futures), Duration.Inf) 

    assert(v === 0) 
    } 

Aber der zurückgegebene Wert 1, nicht 0. Wenn ich schlafen Zeit n*1000-(n+1)*1000 geschaltet, es funktioniert gut (gibt 0 zurück).

Gibt es einen besonderen Effekt, wenn Schlaf auf 0 aufgerufen wird?

Antwort

1

Thread.sleep eine blockierende Operation in Ihrem Future aber kein Signal an die ExecutionContext, dass Sie so tun werden, so wird das Verhalten variiert, je nachdem, was ExecutionContext Sie verwenden und wie viele Prozessoren Ihre Maschine hat. Ihr Code funktioniert wie bei ExecutionContext.global erwartet, wenn Sie blocking hinzufügen:

nums map { n => Future { blocking { Thread.sleep(n*1000); n } } } 
+0

Oh, ich habe vergessen, 'Blockierung'-Block hinzuzufügen. Ich habe übersehen, dass diese Threads in einem Ausführungskontext ausgeführt werden. Ihre Lösung funktioniert völlig einwandfrei. Vielen Dank. –

0

Ich denke, der Name der Funktion ist any so denke ich, Sie any richtig implementieren. Aber wenn Sie die erste wollen, erhalten Sie nur das erste Element aus dem List Argument fs und mit einem Versprechen abzuschließen.

+0

Ich glaube, ich habe das Wort "first" in den Kommentaren missbraucht. Ich wollte - und die Anforderungen beschreiben - den Wert zurückgeben, der zuerst im Zeitbereich berechnet wird. Ich bin mir ziemlich sicher, dass diese Implementierung die Anforderungen erfüllt. –