restore behavior of Future.as[T] and .asSilently[T] (fixes #1088)
- implement both methods equivalently directly on Future - remove implicit conversion futureToAnyOptionAsTypedOption - update docs accordingly
This commit is contained in:
parent
f894ae1818
commit
cdae21e07c
3 changed files with 36 additions and 13 deletions
|
|
@ -377,6 +377,37 @@ sealed trait Future[+T] extends japi.Future[T] {
|
|||
*/
|
||||
def await(atMost: Duration): Future[T]
|
||||
|
||||
/**
|
||||
* Await completion of this Future and return its value if it conforms to A's
|
||||
* erased type. Will throw a ClassCastException if the value does not
|
||||
* conform, or any exception the Future was completed with. Will return None
|
||||
* in case of a timeout.
|
||||
*/
|
||||
def as[A](implicit m: Manifest[A]): Option[A] = {
|
||||
try await catch { case _: FutureTimeoutException ⇒ }
|
||||
value match {
|
||||
case None ⇒ None
|
||||
case Some(Left(ex)) ⇒ throw ex
|
||||
case Some(Right(v)) ⇒ Some(BoxedType(m.erasure).cast(v).asInstanceOf[A])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Await completion of this Future and return its value if it conforms to A's
|
||||
* erased type, None otherwise. Will throw any exception the Future was
|
||||
* completed with. Will return None in case of a timeout.
|
||||
*/
|
||||
def asSilently[A](implicit m: Manifest[A]): Option[A] = {
|
||||
try await catch { case _: FutureTimeoutException ⇒ }
|
||||
value match {
|
||||
case None ⇒ None
|
||||
case Some(Left(ex)) ⇒ throw ex
|
||||
case Some(Right(v)) ⇒
|
||||
try Some(BoxedType(m.erasure).cast(v).asInstanceOf[A])
|
||||
catch { case _: ClassCastException ⇒ None }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether this Future has been completed.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -12,17 +12,6 @@ package object akka {
|
|||
*/
|
||||
implicit def toAnyOptionAsTypedOption(anyOption: Option[Any]) = new AnyOptionAsTypedOption(anyOption)
|
||||
|
||||
/**
|
||||
* Implicitly converts the given Future[_] to a AnyOptionAsTypedOption which offers the method <code>as[T]</code>
|
||||
* to convert an Option[Any] to an Option[T].
|
||||
* This means that the following code is equivalent:
|
||||
* (actor ? "foo").as[Int] (Recommended)
|
||||
*/
|
||||
implicit def futureToAnyOptionAsTypedOption(anyFuture: Future[_]) = new AnyOptionAsTypedOption({
|
||||
try { anyFuture.await } catch { case t: FutureTimeoutException ⇒ }
|
||||
anyFuture.resultOrException
|
||||
})
|
||||
|
||||
private[akka] class AnyOptionAsTypedOption(anyOption: Option[Any]) {
|
||||
/**
|
||||
* Convenience helper to cast the given Option of Any to an Option of the given type. Will throw a ClassCastException
|
||||
|
|
|
|||
|
|
@ -287,8 +287,11 @@ processing another message on this actor).
|
|||
For this purpose, there is the method :meth:`Future.as[T]` which waits until
|
||||
either the future is completed or its timeout expires, whichever comes first.
|
||||
The result is then inspected and returned as :class:`Some[T]` if it was
|
||||
normally completed and the answer’s runtime type matches the desired type; in
|
||||
all other cases :class:`None` is returned.
|
||||
normally completed and the answer’s runtime type matches the desired type; if
|
||||
the future contains an exception or the value cannot be cast to the desired
|
||||
type, it will throw the exception or a :class:`ClassCastException` (if you want
|
||||
to get :obj:`None` in the latter case, use :meth:`Future.asSilently[T]`). In
|
||||
case of a timeout, :obj:`None` is returned.
|
||||
|
||||
.. code-block:: scala
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue