我有一个简单的控制器,用于执行长时间运行的任务,以及用于检查长任务状态的操作:
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)
}
}
在longTerm动作中,HttpSession存在问题。
如果任务闭包中的第一行代码正在使用HttpSession执行某些操作,则其余代码工作正常。但是,如果第一行正在做其他事情,当我尝试访问session.id时,我得到NullPointerException
工作代码示例位于https://github.com/machacekjan/StackOverflowAsyncRequest
有谁知道为什么Grails会这样做?
答案 0 :(得分:0)
此处的问题似乎是您在render()
区块之外执行了tasks
。如果您在render()
块内移动tasks
,则NullPointerException
会消失。
我认为这是因为render()
完成了请求并绕过了Servlet 3异步支持。您需要从task()
执行的操作返回承诺。
不幸的是,render()
似乎不适用于Grails 2.3.7或2.3.10中的异步内容。但这是一个单独的问题。