user267817
user267817

Reputation:

Either wait for a function to finish or timeout after 5 seconds in Akka

I'm trying to wait for a function to finish or timeout after 5 seconds, but whatever I do, I can't prevent the following exception. Interestingly it is caught by the parent actor:

java.util.concurrent.TimeoutException: Futures timed out after [5 seconds]

One of the solutions that I tried (from this question):

val f = Future { dockerClient.execStartCmd(execCreateCmdResponse.getId()).exec() }
val result: Try[InputStream] = Await.ready(f, 5.seconds).value.get

val resultEither = result match {
  case Success(t) => log.info("right")
  case Failure(e) => log.info("left")
}

Upvotes: 1

Views: 2596

Answers (1)

Ivan Stanislavciuc
Ivan Stanislavciuc

Reputation: 7275

Indeed it's possible to achieve this with akka ask pattern. But there is a different solution that can be used without akka.

Wrap your blocking Await code into another Future and register onComplete function

import concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.concurrent.{Await, Future}
import scala.util.{Failure, Success, Try}

val sleepTimeout = 1*1000

val f = Future( Thread.sleep(sleepTimeout); Try(10))
val timeoutFuture = Future(Await.result(f, 5.seconds))
timeoutFuture.onComplete {
  case Success(Success(t))  => println(t)
  case Success(Failure(ex))  => println("error on Try" + ex.getMessage)
  case Failure(e) => println("timeout " + e.getMessage)
}

Explaining match cases

  • Success(Success(t)) First Success is for the timeoutFuture, it means it did not timeout. Second Success is for Try - means no exception were thrown.
  • Success(Failure(ex)) same as first but there is exception within Try
  • Failure(e) this is where timeout is handled.

Upvotes: 3

Related Questions