WSRequest在失败后重试次数

时间:2016-11-28 09:03:02

标签: scala request limit future

以下是我的方法:

def buildWSRequest(url: String, accessToken: String, wsClient: WSClient)
    : (WSRequest, WSResponse) = {
    import AppImplicits._
    val d1 = new java.util.Date()
    val request: WSRequest = wsClient.url(url)
      .withHeaders("Authorization" -> ("Bearer " + accessToken))
      .withHeaders("Content-type" -> "application/json", "Accept" -> "application/json; charset=utf-8")


    var response: WSResponse = null
    try {
      val future = request.get()

      response = scala.concurrent.Await.result(future, duration)

    } catch {
      case ex: Throwable => throw ex.getCause
    }
    return (request, response)
  }

我的呼唤部分是:

var response: WSResponse = buildWSRequest("www.sampletest123.com", params.apply("accessToken").asInstanceOf[String], sslClient)._2

我想重试wsRequest n次,该怎么做?

1 个答案:

答案 0 :(得分:1)

未来n次重试未来是成功的

 def retry[T](future: => Future[T])(retries: Int)(implicit ec: ExecutionContext): Future[T] = {
    val promise = Promise[T]()
    try {
      val f = future
      f onSuccess { case result => promise trySuccess result}
      f onFailure { case th =>
        if (retries > 0) promise tryFailure th
        else retry(future)(retries - 1)
      }
    } catch {
      case th: Throwable => promise tryFailure th
    }
    promise.future
  }

retry将未来的代码块作为名称参数调用,然后运行未来。未来的计算将重试多次,直到成功为止。

首先,创建承诺并将未来返回给用户。然后完成承诺取决于用户给定的未来。如果给定future的使用成功则会立即返回,如果没有重试,则重试计数耗尽。最终承诺完全取决于成功,或者基于剩余的重试次数而失败,如果给定的未来是成功的。另外需要注意的一点是,给定的未来计算可能会失败。因此,try catch块用于处理失败。

重试方法一般可用于任何未来。

对现有代码进行这些更改以利用重试方法

def buildWSRequest(url: String, accessToken: String, wsClient: WSClient): Future[WSReponse] = {
   wsClient.url(url)
      .withHeaders("Authorization" -> ("Bearer " + accessToken))
      .withHeaders("Content-type" -> "application/json", "Accept" -> "application/json; charset=utf-8")
      .get
  }

<强>用法

val requestFuture: Future[WSRequest] = buildWSRequest(....)
retry(requestFuture)(5)

使用隐式类语法的Nice API

implicit class FutureUtils[T](future: => Future[T]) {
    def retry(retries: Int): Future[T] = {
      val promise = Promise[T]()
      try {
        val f = future
        f onSuccess { case result => promise trySuccess result }
        f onFailure { case th =>
          if (retries > 0) promise tryFailure th
          else retry(retries - 1)
        }
      } catch {
        case th: Throwable => promise tryFailure th
      }
      promise.future
    }
  }

使用隐式类,您现在可以使用重试函数,就像它在Future类/接口中声明一样,而不是将未来的代码块作为函数参数传递。

Future(doSomething).retry(10)

一般建议

请勿阻止

使用返回类型与外界进行通信