tags:

views:

159

answers:

2

Futures are very convenient, but in practice, you may need some guarantees on their execution. For example, consider:

import scala.actors.Futures._

def slowFn(time:Int) = {
    Thread.sleep(time * 1000)
    println("%d second fn done".format(time))
}

val fs = List( future(slowFn(2)), future(slowFn(10)) )
awaitAll(5000, fs:_*)
println("5 second expiration. Continuing.")

Thread.sleep(12000)      // ie more calculations
println("done with everything")

The idea is to kick off some slow running functions in parallel. But we wouldn't want to hang forever if the functions executed by the futures don't return. So we use awaitAll() to put a timeout on the futures. But if you run the code, you see that the 5 second timer expires, but the 10 second future continues to run and returns later. The timeout doesn't kill the future; it just limits the join wait.

So how do you kill a future after a timeout period? It seems like futures can't be used in practice unless you're certain that they will return in a known amount of time. Otherwise, you run the risk of losing threads in the thread pool to non-terminating futures until there are none left.

So the questions are: How do you kill futures? What are the intended usage patterns for futures given these risks?

+1  A: 

Futures are intended to be used in settings where you do need to wait for the computation to complete, no matter what. That's why they are described as being used for slow running functions. You want that function's result, but you have other stuff you can be doing meanwhile. In fact, you might have many futures, all independent of each other that you may want to run in parallel, while you wait until all complete.

The timer just provides a wait to get partial results.

Daniel
But since the halting problem hasn't been solved yet :), you have no guarantee that a function will return. Thus, futures may never return. So the original question remains...Point taken about the awaitAll() being used to pull partial results. So that sounds like a usage pattern: pass in a class that saves partial results as they're generated, then use the timer to pull them out.
DrGary
+1  A: 

I think the reason Future can't simply be "killed" is exactly the same as why java.lang.Thread.stop() is deprecated.

While Future is running, a Thread is required. In order to stop a Future without calling stop() on the executing Thread, application specific logic is needed: checking for an application specific flag or the interrupted status of the executing Thread periodically is one way to do it.

Walter Chang