2

I have a simple controller with an action for a long running task and an action for checking a status of the long task:

class AsyncController {

    def index() { }

    def longTerm() {
        session.longTerm = 0
        session.longTermDone = false

        task {
            for (int i; i < 10; i++ ) {
                try {
                    sleep(3000) //NOT WORKING
                    println "  TASK: sessionID ${session.id} value ${session.longTerm++}"
                    //sleep(3000) //WORKING
                } catch (e) {
                    println(e.class.name)
                }
             }

             session.longTermDone = true
        }
        render(text: [] as JSON, status: 200)
    }

    def longTermStatus() {
        println "STATUS: sessionID ${session.id} value ${session.longTerm}"
        render(text: [successCount: session.longTerm, done: session.longTermDone] as JSON, status: 200)
    }
}

In the longTerm action there is a problem with HttpSession.

If the first line of code in the task closure is doing something with HttpSession the rest of the code is working fine. But if the first line is doing something else I get NullPointerException when I try to access session.id

Working code example is at https://github.com/machacekjan/StackOverflowAsyncRequest

Does anyone know why Grails behaves this way?

machaj
  • 288
  • 2
  • 7

1 Answers1

0

The issue here appears to be that you're performing the render() outside of the tasks block. If you move render() inside the tasks block, the NullPointerException disappears.

I think this is because the render() finishes the request and you bypass the Servlet 3 Async support. You need to return a promise from the action, which task() does .

Unfortunately, render() doesn't seem to work with the async stuff in Grails 2.3.7 or 2.3.10. But that's a separate issue.

Peter Ledbrook
  • 4,302
  • 1
  • 21
  • 18