Java Future has cancel
method, which can interrupt the thread, which runs the Future
task. For example, if I wrap an interruptible blocking call in a Java Future
I can interrupt it later.
Scala Future provides no cancel
method. Suppose I wrap an interruptible blocking call in a Scala Future
. How can I interrupt it?
This is not yet a part of the Future
s API, but may be added as an extension in the future.
As a workaround, you could use the firstCompletedOf
to wrap 2 futures - the future you want to cancel and a future that comes from a custom Promise
. You could then cancel the thus created future by failing the promise:
def cancellable[T](f: Future[T])(customCode: => Unit): (() => Unit, Future[T]) = {
val p = Promise[T]
val first = Future firstCompletedOf Seq(p.future, f)
val cancellation: () => Unit = {
() =>
first onFailure { case e => customCode}
p failure new Exception
}
(cancellation, first)
}
Now you can call this on any future to obtain a "cancellable wrapper". Example use-case:
val f = callReturningAFuture()
val (cancel, f1) = cancellable(f) {
cancelTheCallReturningAFuture()
}
// somewhere else in code
if (condition) cancel() else println(Await.result(f1))
EDIT:
For a detailed discussion on cancellation, see Chapter 4 in the Learning concurrent programming in Scala book.