首页 文章

无法理解拉格姆的执行流程

提问于
浏览
0

我正在关注本教程 - 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 将首先打印然后打印记录,但它是相反的 . 不应该首先评估传递给函数的参数吗?

我懂了 . 为什么?

inside logged Received POST /hello3 inside ssc

1 回答

  • 2

    logged 是您编写的函数,它采用 ServiceCall 并使用自己的 ServiceCall 进行装饰 . 稍后,Lagom使用请求标头调用服务调用 . 在服务调用被装饰之前,您正在记录 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 只返回一个 ServiceCall ,Lagom将用它来调用它 .

相关问题