【发布时间】:2020-02-07 19:00:08
【问题描述】:
我正在使用 Akka-hhtp (scala) 将多个 http 批处理请求异步发送到 API,并且想知道当响应代码不是 200 OK 时处理异常的正确方法是什么。
下面是一些伪代码来证明我的观点。
/* Using For comprehension here because the server API has restriction on the amount of data we can send and the time it takes them to process each request. So they require us to send multiple mini requests instead. If one of those fails, then our entire job should fail.*/
val eventuallyResponses = for {
batches <- postBatch(payload)
} yield batches
val eventualResponses = Future.sequence(eventuallyResponses)
/* Do I need to recover here? If I don't, will the actor system terminate? */
eventualResponses.recover { case es =>
log.warn("some message")
List()
}
/* As I said I need to wait for all mini batch requests to complete. If one response is different than 200, then the entire job should fail. */
val result = Await.result(eventualResponses, 10.minutes)
actorSystem.terminate().oncomplete{
case Success(_) =>
if (result.isEmpty) =>
/* This doesn't seem to interrupt the program */
throw new RuntimeException("POST failed")
} else {
log.info("POST Successful")
}
case Failure(ex) =>
log.error("error message $ex")
throw ex
}
def postBatch(payload) = {
val responseFuture: Future[HttpResponse] = httpClient.post(payload)
responseFuture.flatMap{ res =>
res.status match {
case StatusCodes.OK => Future.successful(res)
case _ => Future.failed(new RuntimeException("error message"))
}
}
}
当我们收到与 OK 不同的 StatusCodes 时,上面的代码会抛出异常。它确实通过了result.isEmpty true 的分支,但它似乎并没有停止/中断程序的执行。我需要它来做到这一点,因为这被安排为 Autosys 作业,如果至少有一个批处理请求返回的响应与 200 OK 不同,我需要使作业失败。
如果我不recover 并让异常被抛出(当我们收到非 200 状态码时),Actor System 会正确终止吗?
您知道执行上述操作的好方法吗?
谢谢:)
【问题讨论】:
-
你的情况很难理解。为什么要用理解力?为什么要恢复最终响应?您可以通过 Await.ready 等待未来的结果,如果未来失败,它不会抛出异常。此外,您应该等待参与者系统终止,而不是添加 oncomplete 回调。
-
嗨,Aleksey,感谢您的回复。查看您的问题的答案。 For comprehension 用于创建多个批处理请求(这是因为服务器 API 对我们可以发送的数据量和处理每个请求所需的时间有限制。所以他们要求我们发送多个迷你请求。如果其中一个那些失败了,那么我们的整个工作都应该失败。)你有什么好的例子可以看吗?如果来自小批量请求的任何响应返回非 200,我需要抛出异常。
-
@AlekseyIsachenkov 我在伪代码中添加了一些解释。让我知道这是否清楚,如果您还有其他 cmets :)
-
对于理解并不能帮助您以您期望的方式发送多个请求。如果你不映射或平面映射它,你就不需要恢复未来。您可以匹配未来的结果值。
-
Future没有isEmpty方法,而for是一个空操作,所以这里有些地方不太对劲。你能给我们一些真实的代码吗?
标签: scala exception akka future akka-http