2015-06-10 22 views
0

從Play框架的控制器,我打電話給外部Web服務,在那裏上傳文件。文件上傳後,外部服務器將處理它,我將需要找回處理的文件。scala播放 - 重複的WS調用 - 使其異步

由於處理需要很長時間,因此我每隔幾秒就會持續一次http調用以查看文件是否存在。一旦我找回OK狀態,我再撥打一個電話來檢索處理過的文件。

問題是我必須重複地進行相同的呼叫,每隔幾秒鐘,並且只有在我獲得OK狀態後才能繼續。目前我得到它的工作使用等待 - 我一直等待,並撥打另一個電話,直到我得到OK狀態。

當然,這是封鎖,這是Play中的一大禁忌。

什麼是使這種異步的方法?

這裏是我現在有

<code> 
//keep checking until converted file exists, then download     
futureResponse = fileURLFut.flatMap { 
         convertedFileURL =>           
         //keep checking response status until OK (200)or until too much time passes          
         var counter = 0 
         var respStatus: Int = 0 
         do {       
          if (counter == 30) { 
          //waited too long - interrupt the loop 
          throw new RuntimeException("Converted file not found.") 
          } 
          //TODO this will have to be done without blocking 
          Thread.sleep(2000) 
          counter = counter + 1      
          respStatus = Await.result(  WS.url(convertedFileURL).withAuth(user.get, password.get, AuthScheme.BASIC) 
            .get.map(_.status), duration.Duration(10000, "millis")) 
          Logger.debug("Checking if file exists... " + counter + " status = " + respStatus)             
         } while (respStatus != 200) 

         Logger.debug("File exists. Will download now.") 

         var sss= WS.url(convertedFileURL) 
          .withAuth(user, password, AuthScheme.BASIC) 
          .get 
</code> 
+0

是的假設是正確的,你有沒有其他的界面來查詢該文件的狀態?例如,在文件創建後只響應請求的東西? –

+0

也許使用websockets或類似的東西?然後,您可以在/上傳文件時通知您的客戶。 –

回答

1

嘗試是這樣的代碼:

def runRequest(...): Future[Result] = 
    WS.url(convertedFileURL).withAuth(user.get, password.get, AuthScheme.BASIC) 

def tryOnce(triesLeft: Int): Future[Result] = 
    if (triesLeft == 0) Future.failed(throw new RuntimeException("Converted file not found.")) 
    else runRequest(...) flatMap { res => 
    if (res.status == 200) Future.successful(res) 
    else 
     akka.pattern.after(2 seconds, using = system.scheduler)(tryOnce(triesLeft - 1)) 
    } 

tryOnce(triesLeft = 30)