无法理解lagom中的执行流程
unable to understand execution flow in lagom
我正在学习本教程 - https://www.lagomframework.com/documentation/1.3.x/scala/ServiceImplementation.html
我创建了一个记录服务
//logged takes a ServerServiceCall as argument (serviceCall) and returns a ServerServiceCall.
//ServerServiceCall's compose method creates (composes) another ServerServiceCall
//we are returing the same ServerServiceCall that we received but are logging it using println
def logged[Request,Response](serviceCall:ServerServiceCall[Request,Response]) = {
println("inside logged");
//return new ServerServiceCall after logging request method and uri
ServerServiceCall.compose({
requestHeader=>println(s"Received ${requestHeader.method} ${requestHeader.uri}")
serviceCall
}
)}
我使用记录如下:
override def hello3 = logged(ServerServiceCall
{ (requestHeader,request) =>
println("inside ssc")
val incoming:Option[String] = requestHeader.getHeader("user");
val responseHeader = ResponseHeader.Ok.withHeader("status","authenticated")
incoming match {
case Some(s) => Future.successful((responseHeader,("hello3 found "+s)))
case None => Future.successful((responseHeader,"hello3 didn't find user"))
}
})
我预计会先打印inside ssc
,然后在logged中打印,结果却相反。传递给函数的参数不应该首先被评估吗?
我明白了。为什么?
inside logged
Received POST /hello3
inside ssc
logged
是您编写的一个函数,它接受一个 ServiceCall
并用它自己的 ServiceCall
修饰它。稍后,Lagom 使用请求 header 调用服务调用。您在服务调用被修饰时记录 inside logged
,在它返回到 Lagom 之前,因此在它被调用之前,这就是它首先被调用的原因。这或许可以解释:
def logged[Request, Response](serviceCall:ServerServiceCall[Request, Response]) = {
println("3. inside logged method, composing the service call")
val composed = ServerServiceCall.compose { requestHeader=>
println("6. now Lagom has invoked the logged service call, returning the actual service call that is wrapped")
serviceCall
}
println("4. Returning the composed service call")
composed
}
override def hello3 = {
println("1. create the service call")
val actualServiceCall: ServerServiceCall[Request, Response] = ServerServiceCall { (requestHeader, request) =>
println("7. and now the actual service call has been invoked")
val incoming:Option[String] = requestHeader.getHeader("user");
val responseHeader = ResponseHeader.Ok.withHeader("status","authenticated")
incoming match {
case Some(s) => Future.successful((responseHeader,("hello3 found "+s)))
case None => Future.successful((responseHeader,"hello3 didn't find user"))
}
}
println("2. wrap it in the logged service call")
val loggedServiceCall = logged(actualServiceCall)
println("5. return the composed service call to Lagom")
loggedServiceCall
}
需要记住的重要一点是hello3
方法的调用不是服务调用的调用,hello3
仅仅是returns Lagom 将用来调用它的 ServiceCall
。
我正在学习本教程 - https://www.lagomframework.com/documentation/1.3.x/scala/ServiceImplementation.html
我创建了一个记录服务
//logged takes a ServerServiceCall as argument (serviceCall) and returns a ServerServiceCall.
//ServerServiceCall's compose method creates (composes) another ServerServiceCall
//we are returing the same ServerServiceCall that we received but are logging it using println
def logged[Request,Response](serviceCall:ServerServiceCall[Request,Response]) = {
println("inside logged");
//return new ServerServiceCall after logging request method and uri
ServerServiceCall.compose({
requestHeader=>println(s"Received ${requestHeader.method} ${requestHeader.uri}")
serviceCall
}
)}
我使用记录如下:
override def hello3 = logged(ServerServiceCall
{ (requestHeader,request) =>
println("inside ssc")
val incoming:Option[String] = requestHeader.getHeader("user");
val responseHeader = ResponseHeader.Ok.withHeader("status","authenticated")
incoming match {
case Some(s) => Future.successful((responseHeader,("hello3 found "+s)))
case None => Future.successful((responseHeader,"hello3 didn't find user"))
}
})
我预计会先打印inside ssc
,然后在logged中打印,结果却相反。传递给函数的参数不应该首先被评估吗?
我明白了。为什么?
inside logged
Received POST /hello3
inside ssc
logged
是您编写的一个函数,它接受一个 ServiceCall
并用它自己的 ServiceCall
修饰它。稍后,Lagom 使用请求 header 调用服务调用。您在服务调用被修饰时记录 inside logged
,在它返回到 Lagom 之前,因此在它被调用之前,这就是它首先被调用的原因。这或许可以解释:
def logged[Request, Response](serviceCall:ServerServiceCall[Request, Response]) = {
println("3. inside logged method, composing the service call")
val composed = ServerServiceCall.compose { requestHeader=>
println("6. now Lagom has invoked the logged service call, returning the actual service call that is wrapped")
serviceCall
}
println("4. Returning the composed service call")
composed
}
override def hello3 = {
println("1. create the service call")
val actualServiceCall: ServerServiceCall[Request, Response] = ServerServiceCall { (requestHeader, request) =>
println("7. and now the actual service call has been invoked")
val incoming:Option[String] = requestHeader.getHeader("user");
val responseHeader = ResponseHeader.Ok.withHeader("status","authenticated")
incoming match {
case Some(s) => Future.successful((responseHeader,("hello3 found "+s)))
case None => Future.successful((responseHeader,"hello3 didn't find user"))
}
}
println("2. wrap it in the logged service call")
val loggedServiceCall = logged(actualServiceCall)
println("5. return the composed service call to Lagom")
loggedServiceCall
}
需要记住的重要一点是hello3
方法的调用不是服务调用的调用,hello3
仅仅是returns Lagom 将用来调用它的 ServiceCall
。