繁体   English   中英

将纯Scala中的Play WS API与sbt结合使用

[英]Using the Play WS API from pure Scala with sbt

在这个问题中 ,Scala future被表示为守护线程,因此,如果主线程完成,它不应阻止应用程序停止。

但是,如果我运行以下代码:

object main extends App {
  println("before future\n*************")
  val responseFuture = WS.url("http://www.google.com").withRequestTimeout(5 * 1000).get
  responseFuture.onComplete[Unit](
    _ match {
      case Success(resp) => println(resp.body)
      case Failure(ex) => println(ex.getMessage)
    }
  )
  println(Await.result(responseFuture, Duration.Inf))
  println("after future\n*************")
}

我得到以下输出,这是正确的。

before future
*************
Response(com.ning.http.client.providers.netty.NettyResponse@9913ac)
after future
*************
<!doctype html><html> ... </html>

但是程序一直在运行 ,我必须发送一个SIGINT来终止它。 为什么程序没有终止? 我是否必须明确关闭某些连接? 我猜想,当直接从Play项目中使用它时,其幕后会有一些自动魔术,而在普通的Scala项目中则没有。

编辑: jconsole说:

Name: main
State: WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@14d0af4

Stack trace: 
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
java.util.concurrent.ExecutorCompletionService.take(ExecutorCompletionService.java:193)
sbt.ConcurrentRestrictions$$anon$4.take(ConcurrentRestrictions.scala:196)
...

信封

Scala版本: 2.10.2

Java版本: 1.7.0_09-b05(HotSpot)

播放版本:播放 _2.10”%“ 2.2.1”

sbt版本: 0.12.4

第一次使用WS API时,恰好创建了一个Ning AsyncHttpClient来真正为您完成所有工作。

您可以在WS源代码中查看所有内容

该客户端在WS对象的生存期内保持“活动”状态,并且我怀疑是该对象抢占了阻止主线程完成的锁。

如果您仅添加:

WS.client.close()

在代码段的末尾, AsyncHttpClient正常终止,并且主线程退出。

您还可以通过添加onComplete回调来关闭客户端。 这样,您就不必等待未来。 仅供参考,等待不好!

responseFuture.onComplete {
 _ match {
  case _ => WS.client.close
 }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM