2013-04-13 38 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:那么,我的答案如何提供帮助? –