2017-02-09 27 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

我會將此標記爲答案,因爲它至少可以澄清行爲/期望,而不僅僅是我真正觸發問題/混淆的文檔。 –

相關問題