2013-04-13 81 views
3

是否有任何簡單的方法來重複請求,直到在Play2.1(scala)中獲得成功?以及如何限制嘗試次數?如何在Play中重複請求!框架2.1?

我想要做這樣的事:提前

WS.url("some.url").get().map{ response => 
    val strval = someFunction(response) 
    strval match { 
    case "success" => println("do something after successful request") 
    case "error" => println("repeat same request until success - and repeat maximum N times!") 
    } 
} 

謝謝!

回答

3

未經測試

你可以做這樣的事情:

import scala.concurrent._ 
import play.api.libs.concurrent.Execution.Implicits._ 

def withRetry[T](retries:Int = 5)(f: => Future[T]) = 
    f.recoverWith { 
    case t:Throwable if (retries > 0) => withRetry(retries - 1)(f) 
    } 

然後在自己的代碼,你可以使用這樣的:

withRetry(retries = 2) { 
    WS.url("some.url").get 
    .map { response => 
     require(someFunction(response) != "error", "Please retry") 
     response 
    } 
} 

如果你願意重寫someFunctionResponse => Boolean你可以這樣使用它:

def someFunction(r: Response): Boolean = ??? 

withRetry(retries = 2) { 
    WS.url("some.url").get 
    .filter(someFunction) 
} 
+0

謝謝,EECOLOR!它看起來不錯,但我對使用Await有點困惑,因爲它通常會阻塞線程池。 – krispo

+0

@krispo我不知道Scala處理這個問題。 'Await'對象聲明:'雖然這個方法被阻塞,但'blocking'的內部使用確保底層的ExecutionContext準備妥善管理阻塞。不過有趣的一點! – EECOLOR

+0

爲什麼你需要在未來的等待?爲什麼不只是做'f.recoverWith'? – Mortimer

2

試試這個:

def wSCall = WS.url("http://foo/bar").get() 

def ƒ(response: Response, n: Int): Result = { 
    val strval = someFunction(response) 

    strval match { 
    case "success" => Ok("Ok!") 
    case "error" => { 
     if (n > 0) 
     Async { wSCall.map(response => ƒ(response, n - 1)) } 
     else 
     BadRequest("Fail :(") 
    } 
    } 
} 

Async { wSCall.map(response => ƒ(response, 10)) } 
+0

謝謝,Samy!我喜歡它,稍後會看到。 – krispo

+0

@krispo:那麼,我的答案如何提供幫助? –