Scala Futures - 内置超时? [英] Scala Futures - built in timeout?

查看:26
本文介绍了Scala Futures - 内置超时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

期货的一个方面我从官方教程参考中并不完全理解.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 的结果时,您只会得到超时行为.如果您想使用非阻塞回调 onCompleteonSuccessonFailure,那么您必须滚动自己的超时处理.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆