Scala期货 - 内建超时? [英] Scala Futures - built in timeout?
问题描述
有一个方面的未来,我不完全明白从官方教程ref。 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千兆字节的文本文件...隐含的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已经建立了超时处理请求/响应(?
)之间的消息传递,但不确定是否要开始使用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非常简化的例子滚动自己的可能会像这样的东西。首先,一个用于安排超时的对象:
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
}
c $ c> HashedWheelTimer 我在这里使用是从Netty。
Note that the HashedWheelTimer
I am using here is from Netty.
这篇关于Scala期货 - 内建超时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!