使用 Akka http 处理 HttpResponse 404 上的重试逻辑
Handling Retry Logic on HttpResponse 404 with Akka http
我正在尝试实现一个向外部 REST 端点发出请求的代码,当该端点 returns 为 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))
}
}
问题是当端点 returns 404 时,它以 SUCCESS(HttpResponse(404,...) 的形式出现,因此重试不起作用。任何人都可以指出如何解决这个问题?
onComplete
不改变未来的成败;事实上,函数的返回值被丢弃了。相反,要么在 onComplete
中重试,要么使用 transform
获取新的失败 Future(如果它是 404)然后 recoverWith
.
您应该将 responseFuture
定义为 def
而不是 val
,以便能够多次 运行。
然后您只需执行 responseFuture.filter(_.status.isSuccess())
即可在 404 return 代码(实际上是所有错误代码)上设置 Future.failed
。
您现在可以对此使用您的恢复策略。
我正在尝试实现一个向外部 REST 端点发出请求的代码,当该端点 returns 为 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))
}
}
问题是当端点 returns 404 时,它以 SUCCESS(HttpResponse(404,...) 的形式出现,因此重试不起作用。任何人都可以指出如何解决这个问题?
onComplete
不改变未来的成败;事实上,函数的返回值被丢弃了。相反,要么在 onComplete
中重试,要么使用 transform
获取新的失败 Future(如果它是 404)然后 recoverWith
.
您应该将 responseFuture
定义为 def
而不是 val
,以便能够多次 运行。
然后您只需执行 responseFuture.filter(_.status.isSuccess())
即可在 404 return 代码(实际上是所有错误代码)上设置 Future.failed
。
您现在可以对此使用您的恢复策略。