How to get Some(x) from the results of Futures#awa

2019-08-12 02:57发布

问题:

all.

I wrote the following simple code to test scala.actors._:

// java version "1.7.0_02"
// Scala code runner version 2.9.1.final
// Windows 7 Ultimate sp1 64-bit
import scala.actors._
import scala.collection.mutable.ArrayBuffer

object FutureResults extends App {
    val t1 = System.currentTimeMillis
    val (timeout, results) = (1000, new ArrayBuffer[Future[_]])
    for (i <- 0 until 3) results += new FutureResultsActor !! "execute"
    val options = Futures awaitAll (timeout, results:_*)

    val t2 = System.currentTimeMillis
    println("spent: %,d ms" format t2 - t1)
    options foreach println
    results foreach { i => println("isSet: %b" format i.isSet) }

    Thread sleep timeout

    val t3 = System.currentTimeMillis
    println("spent: %,d ms" format t3 - t1)
    options foreach println
    results foreach { i => println("isSet: %b" format i.isSet) }
}

class FutureResultsActor extends Actor {
    start
    override def act = react { case "execute" => Futures future "done" }
}

This produces:

spent: 1,092 ms
None
None
None
isSet: false
isSet: false
isSet: false

spent: 2,137 ms
None
None
None
isSet: false
isSet: false
isSet: false

Scaladoc of Futures#awaitAll says:

The result of a future that resolved during the time span is its value wrapped in Some.
The result of a future that did not resolve during the time span is None.

Is the timeout value too small? OK, I change the value to 5000 ms and try again:

spent: 5,070 ms
None
None
None
isSet: false
isSet: false
isSet: false

spent: 10,093 ms
None
None
None
isSet: false
isSet: false
isSet: false

All are None. Why?...

How to get Some(x) from the results of Futures#awaitAll?

Is there any incorrect code?

回答1:

Indeed, they're all timing out. Quite the tragedy! The reason: you're not sending a reply from the actor—or at least not properly. I'm not really sure what "Futures future" is, but... my understanding is that the correct way to reply from within an actor is like so:

class FutureResultsActor extends Actor {
  start
  override def act = react { case "execute" => reply("done") } // Use reply()!
}

Doing that got me this result:

spent: 150 ms
Some(done)
Some(done)
Some(done)
isSet: true
isSet: true
isSet: true
spent: 1,165 ms
Some(done)
Some(done)
Some(done)
isSet: true
isSet: true
isSet: true


标签: scala actor