私のサーバー アプリケーションでは、Scalatra、json4s、および Akka を使用しています。
受信するリクエストのほとんどは POST であり、固定の応答でクライアントにすぐに返されます。実際の応答は、クライアントのサーバー ソケットに非同期で送信されます。これを行うにgetRemoteAddr
は、http リクエストから行う必要があります。私は次のコードを試しています:
case class MyJsonParams(foo:String, bar:Int)
class MyServices extends ScalatraServlet {
implicit val formats = DefaultFormats
post("/test") {
withJsonFuture[MyJsonParams]{ params =>
// code that calls request.getRemoteAddr goes here
// sometimes request is null and I get an exception
println(request)
}
}
def withJsonFuture[A](closure: A => Unit)(implicit mf: Manifest[A]) = {
contentType = "text/json"
val params:A = parse(request.body).extract[A]
future{
closure(params)
}
Ok("""{"result":"OK"}""")
}
}
関数の意図は、withJsonFuture
私のルート処理からいくつかの定型文を移動することです。
これは時々機能し ( の null 以外の値を出力しますrequest
)、時々request
null です。これは非常に不可解です。request
私は自分の将来を「閉鎖」しなければならないと思っています。ただし、他に要求が行われていないときに、制御されたテスト シナリオでもエラーが発生します。私は不変であると想像request
します(多分私は間違っていますか?)
この問題を解決するために、コードを次のように変更しました。
case class MyJsonParams(foo:String, bar:Int)
class MyServices extends ScalatraServlet {
implicit val formats = DefaultFormats
post("/test") {
withJsonFuture[MyJsonParams]{ (addr, params) =>
println(addr)
}
}
def withJsonFuture[A](closure: (String, A) => Unit)(implicit mf: Manifest[A]) = {
contentType = "text/json"
val addr = request.getRemoteAddr()
val params:A = parse(request.body).extract[A]
future{
closure(addr, params)
}
Ok("""{"result":"OK"}""")
}
}
これはうまくいくようです。ただし、将来的にエラーを引き起こす可能性のある、同時実行性に関連する悪いプログラミング手法がまだ含まれているかどうかは本当にわかりません (「将来」は、最も一般的な意味で意味されます = その先にあるもの :)。