簡體   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