Scala Futures - 内置超时? [英] Scala Futures - built in timeout?
问题描述
期货的一个方面我从官方教程参考中并不完全理解.http://docs.scala-lang.org/overviews/core/futures.html
there is an aspect of futures that I do not exactly understand from the official tutorial ref. http://docs.scala-lang.org/overviews/core/futures.html
scala 中的期货是否具有某种内置的超时机制?假设下面的示例是一个 5 GB 的文本文件......Implicits.global"的隐含范围最终会导致 onFailure 以非阻塞方式触发还是可以定义?如果没有某种默认超时,这是否意味着成功和失败都不会触发?
Do futures in scala have a built in time-out mechanism of some kind? Let's say the example below was a 5 gigabyte text file... does the implied scope of "Implicits.global" eventually cause onFailure to fire in a non-blocking way or can that be defined? And without a default time-out of some kind, wouldn't that imply it's possible neither success nor failure would ever fire?
import scala.concurrent._
import ExecutionContext.Implicits.global
val firstOccurence: Future[Int] = future {
val source = scala.io.Source.fromFile("myText.txt")
source.toSeq.indexOfSlice("myKeyword")
}
firstOccurence onSuccess {
case idx => println("The keyword first appears at position: " + idx)
}
firstOccurence onFailure {
case t => println("Could not process file: " + t.getMessage)
}
推荐答案
当您使用阻塞来获取 Future
的结果时,您只会得到超时行为.如果您想使用非阻塞回调 onComplete
、onSuccess
或 onFailure
,那么您必须滚动自己的超时处理.Akka 内置了用于 Actor 之间的请求/响应 (?
) 消息传递的超时处理,但不确定您是否要开始使用 Akka.FWIW,在 Akka 中,为了处理超时,它们通过 Future.firstCompletedOf
将两个 Futures
组合在一起,一个代表实际的异步任务,一个代表超时.如果超时计时器(通过 HashedWheelTimer
)首先弹出,则异步回调失败.
You only get timeout behavior when you use blocking to get the results of the Future
. If you want to use the non-blocking callbacks onComplete
, onSuccess
or onFailure
, then you would have to roll your own timeout handling. Akka has built in timeout handling for request/response (?
) messaging between actors, but not sure if you want to start using Akka. FWIW, in Akka, for timeout handling, they compose two Futures
together via Future.firstCompletedOf
, one which represents the actual async task and one that represents the timeout. If the timeout timer (via a HashedWheelTimer
) pops first, you get a failure on the async callback.
一个非常简单的滚动你自己的例子可能是这样的.首先,一个用于调度超时的对象:
A very simplified example of rolling your own might go something like this. First, an object for scheduling timeouts:
import org.jboss.netty.util.{HashedWheelTimer, TimerTask, Timeout}
import java.util.concurrent.TimeUnit
import scala.concurrent.duration.Duration
import scala.concurrent.Promise
import java.util.concurrent.TimeoutException
object TimeoutScheduler{
val timer = new HashedWheelTimer(10, TimeUnit.MILLISECONDS)
def scheduleTimeout(promise:Promise[_], after:Duration) = {
timer.newTimeout(new TimerTask{
def run(timeout:Timeout){
promise.failure(new TimeoutException("Operation timed out after " + after.toMillis + " millis"))
}
}, after.toNanos, TimeUnit.NANOSECONDS)
}
}
然后是一个接受 Future 并为其添加超时行为的函数:
Then a function to take a Future and add timeout behavior to it:
import scala.concurrent.{Future, ExecutionContext, Promise}
import scala.concurrent.duration.Duration
def withTimeout[T](fut:Future[T])(implicit ec:ExecutionContext, after:Duration) = {
val prom = Promise[T]()
val timeout = TimeoutScheduler.scheduleTimeout(prom, after)
val combinedFut = Future.firstCompletedOf(List(fut, prom.future))
fut onComplete{case result => timeout.cancel()}
combinedFut
}
请注意,我在这里使用的 HashedWheelTimer
来自 Netty.
Note that the HashedWheelTimer
I am using here is from Netty.
这篇关于Scala Futures - 内置超时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!