2017-02-09 33 views
0

首先,这在Grails 2.5.4中不是问题。在Grails 3.2.4中,其中有一个.async.task调用的控制器将request.asyncStarted()设置为true,但不提供响应

我正在对我的Grails控制器进行角度AJAX调用,而Grails控制器从不响应。前端调用看起来是这样的..

 $http({ 
      method: "GET", 
      url: actionLink, 
      params: {} 
     }).then(function successCallback(response) { 

      console.log("Yaaay, I got back with some sort of response"); 
     }, function errorCallback(response) { 
      console.log("ERROR PULLING DETAIL") 
     }); 

我已经证实了AJAX调用不调用任何类型的其他控制器的.async.task立即返回,并就好了。然而,这个终点有两个async.task的,我可以告诉第一async.task被定义后asyncStarted标志被触发:

 log.info("ASYNC CHECK-1 - asyncSupported=" + request.asyncSupported + ", asyncStarted=" + request.isAsyncStarted()) 

     def availabilityTask = Item.async.task { 

      JSON availability = itemService.getItemAvailabilityAsJSON(itemInstance) 

      availability 
     } 

     log.info("ASYNC CHECK-2 - asyncSupported=" + request.asyncSupported + ", asyncStarted=" + request.isAsyncStarted()) 

第一request.isAsyncStarted()返回false和第二返回true 。我通风报信这是一个异步的问题,当我把记录一路攀升,并注意到我的日志这样的信息:

2017年2月8日18时47分54秒DEBUG ogweb.servlet.mvc .GrailsDispatcherServlet:离开应对开放的并发处理

以前在Grails的2.5.4我只是简单地调用availabilityTask.get()和渲染指定适当的模型和布局视图。现在看来,我必须这样做是为了获得响应冲回前端:

if (request.isAsyncStarted()) { 
      final AsyncContext ac = request.asyncContext; 
      log.info("Calling to complete async request") 
      ac.dispatch() 
    } 

这似乎恼人的,因为我没有通过任何承诺或可调用到模型和我已经在检查任务是否完成。我是否错过了一些迫使我这样做的事情,或者是这种预期和记录不当的行为(在Grails文档中关于异步的所有地方都没有声明需要调用.dispatch()来刷新异步请求。

UPDATE月,10日2017年

我试图承诺传递到模型,如:

 def availabilityTask = Item.async.task { 
      JSON availability = itemService.getItemAvailabilityAsJSON(itemInstance) 

      availability 
     } 
     render view : "myView", model:[nonAsyncItems, availabilityTask] 

认为结果变压器将检测承诺的模式,但自动调度没”我想模仿Grails Async文档b中看到的内容我想整个模型必须是一个PromiseMap才能使自动调度发生?

从文件科(当我有一个控制器,牵引同步和异步数据,该数据并不理想):

import static grails.async.Promises.* 

    def index() { 
     render view:"myView", model: tasks(one:{ 2 * 2 }, 
              two:{ 3 * 3 }) 
    } 

无论如何,似乎现在我的选择是与任何* .async包装控制器。在更大的任务中关闭任务,或手动管理分派。

回答

1

的确,Grails以前没有启动和异步请求任务。这种行为是错误的,因为如果任务花费时间,那么原始请求可能会完成并在任务完成之前返回到线程池,导致不可预知的行为和异常。

此行为的Grails 3.如果您从您的控制器返回由task方法创建的Promise然后Grails将自动处理dispatch()为您调用已得到纠正。你可以看到这里https://github.com/grails/grails-core/blob/3.2.x/grails-plugin-async/src/main/groovy/org/grails/plugins/web/async/mvc/AsyncActionResultTransformer.groovy#L72

+0

嗨格雷姆,谢谢你的回应。当您之前提到“如果任务需要时间”时,我同意并认为我有责任调用.get或Promises.waitAll来确保我的任务已完成。当我第一次开始使用异步任务时,我遇到了一些问题,我没有意识到我必须这样做,并会得到async null错误(如您所述)。 我编辑我的问题瓦特/更新,以显示我也试图将承诺传递到模型,它没有检测到并自动调度这种方式..是唯一的方法来包装整个事情的任务{}? –

+0

我会将此标记为答案,因为它至少可以澄清行为/期望,而不仅仅是我真正触发问题/混淆的文档。 –

相关问题