【发布时间】:2018-03-07 14:20:14
【问题描述】:
我想从清漆中禁止 URL。我首先要做的是从 consul 那里收集所有健康的 IP。
private def nodeInfo:Future[List[NodeInfo]] = {
val request = HttpRequest(method = HttpMethods.GET, uri = consulUrl)
Future.successful {
Http().singleRequest(request).flatMap(response =>
response.status match {
case OK => Unmarshal(response).to[List[NodeInfo]]
case _ =>
response.entity.toStrict(5.seconds).flatMap { entity =>
val body = entity.data.decodeString("UTF-8")
log.warning(errorMessage(request, response, body))
Future.failed(new IOException(errorMessage(response, body)))
}
})
}.flatMap(value => value)
}
这按预期工作。 在 for comprehension 的帮助下,我想遍历所有这些。
def banFromCache(toBanUrl:String): Future[String] = {
for {
nodes <- nodeInfo
result <- loopNodes(nodes, toBanUrl)
} yield result
}
通过 foreach 循环,我发送 HttpRequest 并为每个循环获取 HttpResponses。但是由于 Future 功能导致的结果是在请求完成之前完成的。
private def loopNodes(nodes:List[NodeInfo], toBanUrl:String):Future[String] = Future {
val banResult = new ListBuffer[String]
nodes.foreach(node => {
banAllHealthy(node, toBanUrl).onComplete {
case Failure(err) =>
banResult += node.Node.Address + " " + err.getMessage
log.error("Request failed: " + node.Node.Address + " " + err.getMessage)
case Success(res) =>
banResult += node.Node.Address + " " + res.toString
log.info("Request success: " + node.Node.Address + " " + res.toString)
}
})
banResult.toList.toString()
}
private def banAllHealthy(nodeInfo:NodeInfo, toBanUrl: String):Future[HttpResponse] = {
def request(): Future[HttpResponse] =
Http().singleRequest(HttpRequest(method = HttpMethods.GET, uri = "http://localhost:9000/healthcheck"))
//Http().singleRequest(HttpRequest(method = HttpMethods.GET, uri = "http://" + nodeInfo.Node.Address + "/" + toBanUrl))
val responseFuture: Future[HttpResponse] = request()
responseFuture
}
这里的路线很简单:
} ~ pathPrefix("ban") {
pathPrefix(Segment) { banpath =>
pathEndOrSingleSlash {
get {
complete(banFromCache(banpath).map(_.asJson))
}
}
}
有没有办法一次显示所有响应?
【问题讨论】: