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:
Roland 2011-08-09 21:37:39 +02:00
parent f894ae1818
commit cdae21e07c
3 changed files with 36 additions and 13 deletions

View file

@ -377,6 +377,37 @@ sealed trait Future[+T] extends japi.Future[T] {
*/ */
def await(atMost: Duration): 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. * Tests whether this Future has been completed.
*/ */

View file

@ -12,17 +12,6 @@ package object akka {
*/ */
implicit def toAnyOptionAsTypedOption(anyOption: Option[Any]) = new AnyOptionAsTypedOption(anyOption) 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]) { 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 * Convenience helper to cast the given Option of Any to an Option of the given type. Will throw a ClassCastException

View file

@ -287,8 +287,11 @@ processing another message on this actor).
For this purpose, there is the method :meth:`Future.as[T]` which waits until 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. 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 The result is then inspected and returned as :class:`Some[T]` if it was
normally completed and the answers runtime type matches the desired type; in normally completed and the answers runtime type matches the desired type; if
all other cases :class:`None` is returned. 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 .. code-block:: scala