Difference Await.ready and Await.result
They both block until the future completes, the difference is just their return type.
The difference is useful when your Future
throws exceptions:
def a = Future { Thread.sleep(2000); 100 }
def b = Future { Thread.sleep(2000); throw new NullPointerException }
Await.ready(a, Duration.Inf) // Future(Success(100))
Await.ready(b, Duration.Inf) // Future(Failure(java.lang.NullPointerException))
Await.result(a, Duration.Inf) // 100
Await.result(b, Duration.Inf) // crash with java.lang.NullPointerException
In general, both are blocking.
The difference is that Await.ready
is blocking until the Future has finished (successful or failed) in given time.
The only one difference is that ready
blocks until the Awaitable
is ready and the result
does yield the result type T
.
Postscriptum:
In practice, if you want to perform some actions like error checking or logging you would take Await.ready(...)
if you want to compose the result and throw an error if something goes wrong take Await.result(...)
.
As rule of thumb - try to avoid Await.
Both are blocking for at most the given Duration
. However, Await.result
tries to return the future result right away and throws an exception if the future failed while Await.ready
returns the completed future from which the result (Success
or Failure
) can safely be extracted via the value
property.
The latter is very handy when you have to deal with a timeout as well:
val future = Future { Thread.sleep(Random.nextInt(2000)); 123 }
Try(Await.ready(future, 1.second)) match {
case Success(f) => f.value.get match {
case Success(res) => // handle future success
case Failure(e) => // handle future failure
}
case Failure(_) => // handle timeout
}
When using Await.result
, the timeout exception and exceptions from failing futures are "mixed up".
Try(Await.result(future, 1.second)) match {
case Success(res) => // we can deal with the result directly
case Failure(e) => // but we might have to figure out if a timeout happened
}