Note that there are some explanatory texts on larger screens.

plurals
  1. POMy http request becomes null inside an Akka future
    primarykey
    data
    text
    <p>My server application uses Scalatra, with json4s, and Akka.</p> <p>Most of the requests it receives are POSTs, and they return immediately to the client with a fixed response. The actual responses are sent asynchronously to a server socket at the client. To do this, I need to <code>getRemoteAddr</code> from the http request. I am trying with the following code:</p> <pre><code>case class MyJsonParams(foo:String, bar:Int) class MyServices extends ScalatraServlet { implicit val formats = DefaultFormats post("/test") { withJsonFuture[MyJsonParams]{ params =&gt; // code that calls request.getRemoteAddr goes here // sometimes request is null and I get an exception println(request) } } def withJsonFuture[A](closure: A =&gt; Unit)(implicit mf: Manifest[A]) = { contentType = "text/json" val params:A = parse(request.body).extract[A] future{ closure(params) } Ok("""{"result":"OK"}""") } } </code></pre> <p>The intention of the <code>withJsonFuture</code> function is to move some boilerplate out of my route processing.</p> <p>This sometimes works (prints a non-null value for <code>request</code>) and sometimes <code>request</code> is null, which I find quite puzzling. I suspect that I must be "closing over" the <code>request</code> in my future. However, the error also happens with controlled test scenarios when there are no other requests going on. I would imagine <code>request</code> to be immutable (maybe I'm wrong?)</p> <p>In an attempt to solve the issue, I have changed my code to the following:</p> <pre><code>case class MyJsonParams(foo:String, bar:Int) class MyServices extends ScalatraServlet { implicit val formats = DefaultFormats post("/test") { withJsonFuture[MyJsonParams]{ (addr, params) =&gt; println(addr) } } def withJsonFuture[A](closure: (String, A) =&gt; 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"}""") } } </code></pre> <p>This seems to work. However, I really don't know if it is still includes any bad concurrency-related programming practice that could cause an error in the future ("future" meant in its most common sense = what lies ahead :).</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload