Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Scalatra is not so well suited for asynchronous code. I recently stumbled on the very same problem as you. The problem is that scalatra tries to make the code as declarative as possible by exposing a dsl that removes as much fuss as possible, and in particular does not require you to explicitly pass data around.</p> <p>I'll try to explain.</p> <p>In your example, the code inside <code>post("/test")</code> is an anonymous function. Notice that it does not take any parameter, not even the current request object. Instead, scalatra will store the current request object inside a thread local value just before it calls your own handler, and you can then get it back through <code>ScalatraServlet.request</code>.</p> <p>This is the classical <em>Dynamic Scope</em> pattern. It has the advantage that you can write many utility methods that access the current request and call them from your handlers, without explicitly passing the request.</p> <p>Now, the problem comes when you use asynchronous code, as you do. In your case, the code inside <code>withJsonFuture</code> executes on another thread than the original thread that the handler was initially called (it will execute on a thread from the <code>ExecutionContext</code>'s thread pool). Thus when accessing the thread local, you are accessing a totally distinct instance of the thread local variable. Simply put, the classical <em>Dynamic Scope</em> pattern is no fit in an asynchronous context.</p> <p>The solution here is to capture the request at the very start of your handler, and then exclusively reference that:</p> <pre><code>post("/test") { val currentRequest = request withJsonFuture[MyJsonParams]{ params =&gt; // code that calls request.getRemoteAddr goes here // sometimes request is null and I get an exception println(currentRequest) } } </code></pre> <p>Quite frankly, this is too easy to get wrong IMHO, so I would personally avoid using Scalatra altogether if you are in an synchronous context.</p>
    singulars
    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. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      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