How to cancel Future in Scala? How to cancel Future in Scala? multithreading multithreading

How to cancel Future in Scala?


This is not yet a part of the Futures 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 codeif (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.


I haven't tested this, but this expands on the answer of Pablo Francisco PĂ©rez Hidalgo. Instead of blocking waiting for the java Future, we use an intermediate Promise instead.

import java.util.concurrent.{Callable, FutureTask}import scala.concurrent.{ExecutionContext, Promise}import scala.util.Tryclass Cancellable[T](executionContext: ExecutionContext, todo: => T) {  private val promise = Promise[T]()  def future = promise.future  private val jf: FutureTask[T] = new FutureTask[T](    new Callable[T] {      override def call(): T = todo    }  ) {    override def done() = promise.complete(Try(get()))  }  def cancel(): Unit = jf.cancel(true)  executionContext.execute(jf)}object Cancellable {  def apply[T](todo: => T)(implicit executionContext: ExecutionContext): Cancellable[T] =    new Cancellable[T](executionContext, todo)}


By cancelling I guess you would like to violently interrupt the future.

Found this segment of code: https://gist.github.com/viktorklang/5409467

Did a few tests and seems to work fine!

Enjoy :)