Scala future app在完成之前终止

时间:2014-05-08 16:52:41

标签: scala akka scalaxb

试图让我的第一个期货用完并运行并进行类似于Akka in Action MEAP手册中概述的示例的测试。我想调用Web服务并在将来返回结果。我正在使用scalaxb来访问Web服务。我已经概述了下面的代码,但是当我运行它时,应用终止而不等待服务的响应。也许有人可以告诉我我错过了什么?

import scala.util._
import control.NonFatal
import scala.concurrent._
import ExecutionContext.Implicits.global

object Test {


    val service = (new MyServiceBindings with scalaxb.Soap11Clients with scalaxb.DispatchHttpClients {}).service

    def test = {

        val f = future {

            service.someCall() match {
                case Right(resp) => resp
                case Left(fault) => throw new Exception("Fault: " + fault)}
            }
        }

        f.onComplete {
            case Success(resp) => println("Resp: " + resp)
            case Failure(NonFatal(e)) => println("Fail: " + e)
        }
    }

    def main(args: Array[String]): Unit = {
        test
    }
}

2 个答案:

答案 0 :(得分:5)

它终止,因为在Test中执行的主线程已经完成。 Dispatch库内部使用的线程不会阻止程序退出。

您需要等待未来,因为这是您的测试应用程序唯一要做的事情。把它放在onComplete语句之后。

import scala.concurrent.duration._ Await.ready(f, 10.seconds)

现在请记住,这通常是不好的做法。你需要它,因为你的测试应用程序没有做任何其他事情,但在一个真实的应用程序中,你不希望在每次期货通话后阻止,因为这会否定使用期货的点。

答案 1 :(得分:0)

<强> 您可以通过向测试应用程序添加以下逻辑来在主要功能中对此进行修补:

def main(args: Array[String]) :  Unit = {

  // Assuming test is a future that did not complete yet.
  while(!test.isCompleted) { 
       Thread.sleep(100) 
  }
  // Software exits here only after future is completed.  
}

或者如果你有很多未来,你可以用这种方式实现它:

//假设你有 - &gt; listOfFutures = ArrayBuffer [Future]

def main(args: Array[String]) : Unit = {
   while(!listOfFutures.isEmpty) {
      listOfFutures.foreach {
         future =>
          if(future.isCompleted) {
             listOfFutures -= future
          }
      }
      //checks which futures are completed every half-a-second
      Thread.sleep(500) 
   }
   // Program exits after all futures have been completed.
}