为scala方法设置超时

时间:2018-02-11 10:43:24

标签: scala future

我正在尝试为方法设置超时。我在测试中有以下代码。 f的返回值是我定义的特殊类型。它返回Interval(Int, Int)

val f = evalfunc (a, b)

evalfunc使用外部单纯形求解器。有时它会卡在这里。我想为此设置超时。我在this之后尝试了未来超时。

def runWithTimeout[T](timeout: Long)(f: => T) : Option[T] = {
 Await.result(Future(f), timeout seconds).asInstanceOf[Option[T]] } 

def runWithTimeout[T](timeout: Long, default: T)(f: => T) : T = { runWithTimeout(timeout)(f).getOrElse(default)}

val f = runWithTimeout(300){evalfunc(a, b)}

但它说,tools.Interval不能转换为scala.Option。如何在此功能中添加计时器?我需要val f作为Interval(Int, Int),然后我在f进行一些计算。

我的问题是我尝试使用链接中给出的解决方案。在我的情况下,我试图为返回Interval(Int, Int)的方法添加超时,并且它说它需要scala.Option。

1 个答案:

答案 0 :(得分:2)

为什么首先将它投射到Optiondocumentation for Await.result表示result[T]的返回类型为T,而不是Option[T]

你可以使用Option[T],但为此,如果TimeoutException方法在指定的时间限制内没有成功,则必须捕获引发的result

尝试类似这样的事情:

import scala.concurrent._
import scala.concurrent.duration._

def runWithTimeout[T]
  (timeout: Long)
  (f: => T)
  (implicit ec: ExecutionContext)
: Option[T] = {
  try {
    Some(Await.result(Future(f), timeout.seconds))
  } catch {
    case e: TimeoutException => None
  }
}

请注意,所有这些超时和等待时间只影响正在等待的程序部分。它不会以任何方式影响复杂的数值过程f的执行:一旦它启动,无论如何都会运行,如果它在同一个JVM中运行,则无法阻止它,因为JVM是不是操作系统。如果您希望能够实际停止执行f,那么您有两个选择:

  • f合作,也就是说,它应该偶尔检查结果是否仍然需要,如果由于超时而不再需要结果,则停止。
  • 在JVM之外作为一个单独的进程运行f,在超时后使用操作系统的工具将其终止。