aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/scala/async/ExprBuilder.scala
diff options
context:
space:
mode:
authorphaller <hallerp@gmail.com>2012-11-26 17:28:51 +0100
committerphaller <hallerp@gmail.com>2012-11-26 23:26:16 +0100
commit9ea2cc44e98c110843780aef09c7d1a695458be3 (patch)
tree3b7eb7ad3c8e6b983675a020d1f4fe7edb72bdca /src/main/scala/scala/async/ExprBuilder.scala
parent3fd51865dfcb6121f84145f4504abd0f80bf6cca (diff)
downloadscala-async-9ea2cc44e98c110843780aef09c7d1a695458be3.tar.gz
scala-async-9ea2cc44e98c110843780aef09c7d1a695458be3.tar.bz2
scala-async-9ea2cc44e98c110843780aef09c7d1a695458be3.zip
Fix #42 - Futures created by async are not properly completed with exceptions
This augments the on-complete handler for an async state with await as follows: if (tr.isFailure) result$async.complete(tr.asInstanceOf[Try[T]]) else { <resultName> = tr.get.asInstanceOf[<resultType>] <nextState> <mkResumeApply> }
Diffstat (limited to 'src/main/scala/scala/async/ExprBuilder.scala')
-rw-r--r--src/main/scala/scala/async/ExprBuilder.scala29
1 files changed, 24 insertions, 5 deletions
diff --git a/src/main/scala/scala/async/ExprBuilder.scala b/src/main/scala/scala/async/ExprBuilder.scala
index 7b4ccb8..ef27672 100644
--- a/src/main/scala/scala/async/ExprBuilder.scala
+++ b/src/main/scala/scala/async/ExprBuilder.scala
@@ -30,7 +30,7 @@ private[async] final case class ExprBuilder[C <: Context, FS <: FutureSystem](c:
def mkHandlerCaseForState: CaseDef
- def mkOnCompleteHandler: Option[CaseDef] = None
+ def mkOnCompleteHandler[T: c.WeakTypeTag]: Option[CaseDef] = None
def stats: List[Tree]
@@ -75,13 +75,32 @@ private[async] final case class ExprBuilder[C <: Context, FS <: FutureSystem](c:
mkHandlerCase(state, stats :+ callOnComplete)
}
- override def mkOnCompleteHandler: Option[CaseDef] = {
+ override def mkOnCompleteHandler[T: c.WeakTypeTag]: Option[CaseDef] = {
val tryGetTree =
Assign(
Ident(awaitable.resultName),
TypeApply(Select(Select(Ident(name.tr), Try_get), newTermName("asInstanceOf")), List(TypeTree(awaitable.resultType)))
)
- Some(mkHandlerCase(state, List(tryGetTree, mkStateTree(nextState), mkResumeApply)))
+
+ /* if (tr.isFailure)
+ * result$async.complete(tr.asInstanceOf[Try[T]])
+ * else {
+ * <resultName> = tr.get.asInstanceOf[<resultType>]
+ * <nextState>
+ * <mkResumeApply>
+ * }
+ */
+ val ifIsFailureTree =
+ If(Select(Ident(name.tr), Try_isFailure),
+ futureSystemOps.completeProm[T](
+ c.Expr[futureSystem.Prom[T]](Ident(name.result)),
+ c.Expr[scala.util.Try[T]](
+ TypeApply(Select(Ident(name.tr), newTermName("asInstanceOf")),
+ List(TypeTree(weakTypeOf[scala.util.Try[T]]))))).tree,
+ Block(List(tryGetTree, mkStateTree(nextState), mkResumeApply): _*)
+ )
+
+ Some(mkHandlerCase(state, List(ifIsFailureTree)))
}
override val toString: String =
@@ -276,7 +295,7 @@ private[async] final case class ExprBuilder[C <: Context, FS <: FutureSystem](c:
trait AsyncBlock {
def asyncStates: List[AsyncState]
- def onCompleteHandler: Tree
+ def onCompleteHandler[T: c.WeakTypeTag]: Tree
def resumeFunTree[T]: Tree
}
@@ -320,7 +339,7 @@ private[async] final case class ExprBuilder[C <: Context, FS <: FutureSystem](c:
* resume()
* }
*/
- val onCompleteHandler: Tree = Match(Ident(name.state), initStates.flatMap(_.mkOnCompleteHandler).toList)
+ def onCompleteHandler[T: c.WeakTypeTag]: Tree = Match(Ident(name.state), initStates.flatMap(_.mkOnCompleteHandler[T]).toList)
/**
* def resume(): Unit = {