我需要调用一个可能返回或不返回及时结果的服务。我希望能写是否有一个标准的Scala函数用于运行带超时的块?
val result = runWithTimeout(5000, valReturnedOnTimeout) { service.fetch }
有没有一个标准功能,将做的工作 - 像Ruby的timeout?
我需要调用一个可能返回或不返回及时结果的服务。我希望能写是否有一个标准的Scala函数用于运行带超时的块?
val result = runWithTimeout(5000, valReturnedOnTimeout) { service.fetch }
有没有一个标准功能,将做的工作 - 像Ruby的timeout?
以信誉其他的答案 - 在没有任何标准库函数,我已经走下了期货路线。
import scala.concurrent._
import scala.concurrent.duration._
def runWithTimeout[T](timeoutMs: Long)(f: => T) : Option[T] = {
Await.result(Future(f), timeMins milliseconds).asInstanceOf[Option[T]]
}
def runWithTimeout[T](timeoutMs: Long, default: T)(f: => T) : T = {
runWithTimeout(timeoutMs)(f).getOrElse(default)
}
这样
@Test def test {
runWithTimeout(50) { "result" } should equal (Some("result"))
runWithTimeout(50) { Thread.sleep(100); "result" } should equal (None)
runWithTimeout(50, "no result") { "result" } should equal ("result")
runWithTimeout(50, "no result") { Thread.sleep(100); "result" } should equal("no result")
}
我会的任何反馈表示感谢,这是否是一个很好的斯卡拉风格!
我已经扩展了这个来处理异常在http://stackoverflow.com/questions/6229778 – 2011-06-06 08:10:58
您可以在一个新的线程中启动它,然后等待它完成Thread.join。如果你传递一个参数来加入,它最多等待几毫秒。
val t = new Thread {
override def run() {
//...
}
}
t.start()
t.join(5000)
谢谢,我也可以使用Executors框架。但我在检查我是不是缺少内置或惯用的东西。 – 2011-06-03 13:46:52
你可以使用一个未来
import scala.actors.Futures._
val myfuture =
future {
Thread.sleep(5000)
println("<future>")
"future "
}
awaitAll(300,myfuture) foreach println _
但也看看Circuit Breaker for Scala是的 Circuit Breaker Pattern一个实现。基本上,它可以让你控制超时,如果发生故障访问外部资源
使用看起来像这样在斯卡拉(自述)会发生什么:
. . .
addCircuitBreaker("test", CircuitBreakerConfiguration(timeout=100,failureThreshold=10))
. . .
class Test extends UsingCircuitBreaker {
def myMethodWorkingFine = {
withCircuitBreaker("test") {
. . .
}
}
def myMethodDoingWrong = {
withCircuitBreaker("test") {
require(false,"FUBAR!!!")
}
}
}
我喜欢断路器,但我想标准库中没有任何东西。我会尽量写一些基于期货的东西来保持简单。 – 2011-06-03 15:06:17
请注意,未来阻塞线程。 http://stackoverflow.com/q/5646879/203968因此,多次呼叫您的客户端可能会导致您的线程挨饿。因此断路器。当你认为通话不可能工作时,你可以“打破电路” – oluies 2011-06-03 15:39:32
是的,我将不得不考虑这一点,因为通话在我的网络层,所以我可以每个浏览器都有一个。我可能必须让浏览器轮询并最终使用Executors。 – 2011-06-03 15:48:18
还没有提到的东西是等待,这是一个关于actors包的Futures对象的方法。 awaitEither返回从第一一对期货的结果来完成,因此,例如像这样,可以使用:
awaitEither(future{task}, alarm(timeoutPeriod))
,然后在方法装扮成提示:
def runWithTimeout[T](timeoutPeriod: Int, timeoutValue: T)(task: => T) = {
awaitEither(future{task}, alarm(timeoutPeriod)) match {case() => timeoutValue case x => x}
}
报警返回可赋值给Any类型的val的单元,因此awaitEither返回可与模式匹配的东西。
我认为,当@ pr1001指出'报警',但认为我们可能会最终开始另一个线程的报警 - 这似乎有点矫枉过正。它确实使一个很好的短暂的表达。 – 2011-06-03 21:36:19
是的,我知道使用Actor可以解决这个问题,但对于这样一个简单的问题似乎过度。 – 2011-06-03 13:33:35
相关http://stackoverflow.com/q/5797666/132374 – 2013-10-30 03:07:53