🎓 A1Learner
🔍
0 of 45 lessons completed

Future Timeouts

A future timeout is a limit on how long a wait for a result may last. The wait ends with an error when the limit passes before the result arrives.

A result inside the limit prints normally

The future already holds 42. The wait ends at once, well inside five seconds.

import scala.concurrent.{Future, Await, Promise}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.*
import java.util.concurrent.TimeoutException
@main def main(): Unit =
  println(Await.result(Future(42), 5.seconds))

A wait past the limit is caught

The promise never completes. The catch block prints a fixed message instead of a value.

import scala.concurrent.{Future, Await, Promise}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.*
import java.util.concurrent.TimeoutException
@main def main(): Unit =
  val promise = Promise[Int]()
  try
    println(Await.result(promise.future, 200.millis))
  catch
    case _: TimeoutException => println("Timed out")

A timeout can give a fallback number

The promise never completes. The catch block supplies zero as the fallback value.

import scala.concurrent.{Future, Await, Promise}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.*
import java.util.concurrent.TimeoutException
@main def main(): Unit =
  val promise = Promise[Int]()
  val result = try
    Await.result(promise.future, 100.millis)
  catch
    case _: TimeoutException => 0
  println(result)

Example

import scala.concurrent.{Future, Await, Promise}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.*
import java.util.concurrent.TimeoutException
def waitOrFallback(future: Future[Int], fallback: Int): Int =
  try Await.result(future, 200.millis)
  catch case _: TimeoutException => fallback
@main def main(): Unit =
  println(waitOrFallback(Future(30), 0))
  println(waitOrFallback(Promise[Int]().future, 99))

Key points

  • Duration: A duration is a length of time such as 200 milliseconds.
  • Use Await.result with a duration to wait for a future for at most that long.
  • TimeoutException: A TimeoutException is the error raised when the wait limit passes.
  • Use a try block with a catch block to handle the error and give a fallback value.
  • Fallback: A fallback is a safe value used when the real result does not arrive in time.

In this example, waitOrFallback awaits the first future and prints its value 30. Then it awaits a promise that never completes, catches the timeout, and prints the fallback 99.

Note

A timeout stops the wait, but it does not stop the future itself from finishing later.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Scastie

Exercise

What happens when Await.result waits 100 milliseconds for a promise that never completes?