Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Await a future, receive an either

Tags:

scala

future

I'd like to await a scala future that may have failed. If I use Await.result the exception will be thrown. Instead, if I have f: Future[String] I would like a method Await.resultOpt(f): Option[String] or Await.resultEither(f): Either[String].

I could get this by using scala.util.control.Exception.catching or I could f map (Right(_)) recover { case t: Throwable => Left(t) }, but there must be a more straightforward way.

like image 634
schmmd Avatar asked Jan 28 '14 21:01

schmmd


People also ask

What is await result in Scala?

Await. result tries to return the Future result as soon as possible and throws an exception if the Future fails with an exception while Await. ready returns the completed Future from which the result (Success or Failure) can safely be extracted.

How do you complete a Future in Scala?

The most general form of registering a callback is by using the onComplete method, which takes a callback function of type Try[T] => U . The callback is applied to the value of type Success[T] if the future completes successfully, or to a value of type Failure[T] otherwise.

What is Future and promise in Scala?

The Promise is a writable, single-assignment container that completes a Future. The Promise is similar to the Future. However, the Future is about the read-side of an asynchronous operation, while the Promise is about the write-side.

How does Scala Future work?

Future represents a result of an asynchronous computation that may or may not be available yet. When we create a new Future, Scala spawns a new thread and executes its code. Once the execution is finished, the result of the computation (value or exception) will be assigned to the Future.


1 Answers

You could use Await.ready which simply blocks until the Future has either succeeded or failed, then returns a reference back to that Future.

From there, you would probably want to get the Future's value, which is an Option[Try[T]]. Due to the Await.ready call, it should be safe to assume that the value is a Some. Then it's just a matter of mapping between a Try[T] and an Either[Throwable, T].

The short version:

val f: Future[T] = ...  val result: Try[T] = Await.ready(f, Duration.Inf).value.get  val resultEither = result match {   case Success(t) => Right(t)   case Failure(e) => Left(e) } 
like image 59
Dylan Avatar answered Oct 20 '22 23:10

Dylan