使用Akka http处理HttpResponse 404上的重试逻辑

时间:2017-03-23 18:47:16

标签: java scala akka httpresponse akka-http

我正在尝试实现一个向外部REST端点发出请求的代码,当该端点返回404时,它应该在有限时间内重试。

HttpRequest类似于

val responseFuture = Http().singleRequest(HttpRequest(method = requestMethod,
    uri = url,
    entity = HttpEntity(requestBody).withContentType(ContentTypes.`application/json`)
))

,响应处理为

responseFuture.onComplete {
    case Success(r) =>
      if (r.status.isFailure()) Future.failed(new Exception("request failed with status 404"))
      else r
    case Failure(e) => throw e
}

我的重试逻辑是:

def retryFuture[T](retries: Int, delay: FiniteDuration = 1.second)(fn: => Future[T])(implicit ec: ExecutionContext, s: Scheduler): Future[T] = {
    fn.recoverWith {
      case _ if retries > 0 => after(delay, s)(retryFuture(retries - 1, delay)(fn))
    }
}

问题是当端点返回404时,它来自SUCCESS(HttpResponse(404,...),因此重试不起作用。任何人都可以指出可以做些什么来解决这个问题?

2 个答案:

答案 0 :(得分:0)

onComplete并未改变未来的成败;实际上,函数的返回值被丢弃。相反,要么在onComplete中重试,要么使用transform来获取新的失败的未来,如果它是404,然后是recoverWith

答案 1 :(得分:0)

您应该将responseFuture定义为def而不是val,以便能够多次运行。

然后,您只需要responseFuture.filter(_.status.isSuccess())在404返回代码上显示Future.failed(实际上是在所有错误代码上)。

您现在可以使用恢复策略。