summaryrefslogtreecommitdiff
path: root/cask/src/cask/main/Main.scala
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2018-08-08 15:22:02 +0800
committerLi Haoyi <haoyi.sg@gmail.com>2018-08-08 15:22:02 +0800
commita5320694193fd86b639c53a91fa24fb7f8ea914e (patch)
tree84d5d94f1fa0a6aeee2b7dc81b1f0276e2f38994 /cask/src/cask/main/Main.scala
parenta89ebd17dab5af6814d58f02d410acb1eb60e592 (diff)
downloadcask-a5320694193fd86b639c53a91fa24fb7f8ea914e.tar.gz
cask-a5320694193fd86b639c53a91fa24fb7f8ea914e.tar.bz2
cask-a5320694193fd86b639c53a91fa24fb7f8ea914e.zip
Refactor decorators into a more traditional delegation model, and use that to implement endpoint-scoped transactions using Quill
Diffstat (limited to 'cask/src/cask/main/Main.scala')
-rw-r--r--cask/src/cask/main/Main.scala41
1 files changed, 17 insertions, 24 deletions
diff --git a/cask/src/cask/main/Main.scala b/cask/src/cask/main/Main.scala
index fb07e77..65655fc 100644
--- a/cask/src/cask/main/Main.scala
+++ b/cask/src/cask/main/Main.scala
@@ -33,7 +33,7 @@ abstract class BaseMain{
)
}.toMap
- def writeResponse(exchange: HttpServerExchange, response: BaseResponse) = {
+ def writeResponse(exchange: HttpServerExchange, response: Response) = {
response.headers.foreach{case (k, v) =>
exchange.getResponseHeaders.put(new HttpString(k), v)
}
@@ -55,30 +55,22 @@ abstract class BaseMain{
def handleRequest(exchange: HttpServerExchange): Unit = {
routeTries(exchange.getRequestMethod.toString.toLowerCase()).lookup(Util.splitPath(exchange.getRequestPath).toList, Map()) match{
case None => writeResponse(exchange, handleError(404))
- case Some(((routes, metadata), bindings, remaining)) =>
- val params = for{
- decoratorParams <- Util.sequenceEither[Response, cask.main.Decor[_], Seq](
- metadata.decorators.map(e => e.getRawParams(ParamContext(exchange, remaining)))
- )
- endpointParams <- metadata.endpoint.getRawParams(ParamContext(exchange, remaining))
- } yield (
- (endpointParams.params ++ bindings.mapValues(metadata.endpoint.wrapPathSegment)) +:
- decoratorParams.map(_.params),
- () => {endpointParams.cleanup(); decoratorParams.foreach(_.cleanup())}
- )
+ case Some(((routes, metadata), extBindings, remaining)) =>
+ val ctx = ParamContext(exchange, remaining)
+ def rec(remaining: List[Decorator],
+ bindings: List[Map[String, Any]]): Router.Result[Response] = remaining match{
+ case head :: rest => head.wrapMethodOutput(ctx, args => rec(rest, args :: bindings))
+ case Nil =>
+ metadata.endpoint.wrapMethodOutput(ctx, epBindings =>
+ metadata.entryPoint
+ .asInstanceOf[EntryPoint[cask.main.Routes, cask.model.ParamContext]]
+ .invoke(routes, ctx, (epBindings ++ extBindings.mapValues(metadata.endpoint.wrapPathSegment)) :: bindings.reverse)
+ .asInstanceOf[Router.Result[Nothing]]
+ )
- val result = params match{
- case Left(resp) => resp
- case Right((paramValues, cleanup)) =>
- try metadata.entryPoint
- .asInstanceOf[EntryPoint[cask.main.Routes, cask.model.ParamContext]]
- .invoke(routes, ParamContext(exchange, remaining), paramValues)
- finally cleanup()
}
-
-
- result match{
- case Router.Result.Success(response: BaseResponse) => writeResponse(exchange, response)
+ rec(metadata.decorators.toList, Nil)match{
+ case Router.Result.Success(response: Response) => writeResponse(exchange, response)
case e: Router.Result.Error =>
writeResponse(exchange,
@@ -88,7 +80,8 @@ abstract class BaseMain{
metadata.entryPoint.asInstanceOf[EntryPoint[cask.main.Routes, _]],
e
),
- statusCode = 500)
+ statusCode = 500
+ )
)
}
}