2

每当我运行一个使用 a 结果的 scala 进程时Future(通过Await, map,onComplete等),它永远不会退出,迫使我们手动终止该进程。无论我使用extends App还是仅使用标准def main(args: Array[String])方法,都会发生这种情况。

在我看来,这与ThreadPoolExecutorscala 将旋转以执行在Future函数末尾挂起的 is 有关,但我似乎无法处理它来关闭它。

例如,以下代码将无法退出:

object ExecuteApi extends App with StrictLogging{

  lazy val config = StratumConfiguration.setupConfiguration()
  lazy val apiEndpoint = config.getProperty("APIEndpoint").split("/").head
  lazy val packetApiPath = "packets/getpackets"

  val resourceNames = sys.env.getOrElse("ResourceNames", "").stripMargin.split("[\n\\s]+").map(_.trim).filterNot(_.isEmpty)
  val searchBody =
  s"""{
    |  "resourceNames": [
    |    "${(resourceNames).mkString("\",\"")}"
    |  ]
    |}""".stripMargin
    logger.info(searchBody)
    val responseFuture = AmazonAsyncApiGatewayHelper.executeHttpRequest(apiEndpoint, searchBody, Some(packetApiPath), Some("api"))
    val response = Await.result(responseFuture, Duration(25, TimeUnit.SECONDS))
    val layerDefinitions = Json.parse(response)
    println(Json.prettyPrint(layerDefinitions))
}

虽然这段代码退出得很好(唯一的变化是返回未来的异步版本,然后等待):

object ExecuteAPI extends App with StrictLogging{

  lazy val config = Configuration.setupConfiguration()
  lazy val apiEndpoint = config.getProperty("APIEndpoint").split("/").head
  lazy val packetApiPath = "packets/getpackets"

  val resourceNames = sys.env.getOrElse("ResourceNames", "").stripMargin.split("\n").map(_.trim).filterNot(_.isEmpty)

  val searchBody =
  s"""{
    |  "resourceNames": [
    |    "${(resourceNames).mkString("\",\"")}"
    |  ]
    |}""".stripMargin
    logger.info(searchBody)
    val layersResponse = AmazonapiGatewayHelper.executeHttpRequest(apiEndpoint, searchBody, Some(packetApiPath), Some("api"))
    val layerDefinitions = Json.parse(layersResponse)
    println(Json.prettyPrint(layerDefinitions))
}

中的代码AmazonAsyncApiGatewayHelper最终通过执行 Play 库 HTTP 客户端来创建 Future。但是,我们在以其他方式执行 Futures 时也看到了这一点:

val request = wsClient.url(fullUrl)
    .withRequestTimeout(readTimeout)
val requestWithHeaders = headers.foldLeft(request) { (r, h) =>
  r.withHeaders(h)
}
val playResponseFuture = requestWithHeaders.post(requestBody)
4

2 回答 2

0

我们最终找到了问题所在。Play wsClient 需要一个参与者系统(从 Play 2.5 开始)。在退出主类之前,我们需要手动终止这个actor系统。退出的代码如下所示:

object ExecuteAPI extends App with StrictLogging{
 try {
  lazy val config = Configuration.setupConfiguration()
  lazy val apiEndpoint = config.getProperty("APIEndpoint").split("/").head
  lazy val packetApiPath = "packets/getpackets"

  val resourceNames = sys.env.getOrElse("ResourceNames", "").stripMargin.split("\n").map(_.trim).filterNot(_.isEmpty)

  val searchBody =
  s"""{
    |  "resourceNames": [
    |    "${(resourceNames).mkString("\",\"")}"
    |  ]
    |}""".stripMargin
    logger.info(searchBody)
    val responseFuture = AmazonAsyncApiGatewayHelper.executeHttpRequest(apiEndpoint, searchBody, Some(packetApiPath), Some("api"))
    val response = Await.result(responseFuture, Duration(25, TimeUnit.SECONDS))
    val layerDefinitions = Json.parse(response)
    println(Json.prettyPrint(layerDefinitions))
 } finally {
    AmazonAsyncApiGatewayHelper.client.actorSystem.terminate()
 }
}
于 2016-10-16T22:27:06.410 回答
-1

您可以映射未​​来价值并Thread.sleep()在最后添加。

val result = layersResponse  map { futureValue =>
 Json.parse(layerResponse)
}

Thread.sleep(10000)
println(Json.prettyPrint(result))
于 2016-10-13T18:56:06.380 回答