从官方教程参考中我还没有完全理解未来的一个方面 . http://docs.scala-lang.org/overviews/core/futures.html
scala中的期货是否具有某种内置的超时机制?假设下面的例子是一个5千兆字节的文本文件......“Implicits.global”的隐含范围是否会导致onFailure以非阻塞方式触发或者可以定义?没有某种默认的超时时间,这是否意味着它既不会成功也不会失败?
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)
}
10 回答
当您使用阻止来获取
Future
的结果时,您只会获得超时行为 . 如果要使用非阻塞回调onComplete
,onSuccess
或onFailure
,则必须滚动自己的超时处理 . Akka内置了针对演员之间的请求/响应(?
)消息传递的超时处理,但不确定是否要开始使用Akka . FWIW,在Akka中,对于超时处理,它们通过Future.firstCompletedOf
一起组成两个Futures
,一个代表实际的异步任务,另一个代表超时 . 如果超时计时器(通过HashedWheelTimer
)首先弹出,则异步回调会出现故障 .滚动自己的一个非常简单的例子可能是这样的 . 首先,一个用于调度超时的对象:
然后是一个函数来获取Future并为其添加超时行为:
请注意,我在这里使用的
HashedWheelTimer
来自Netty .我刚为同事创建了一个
TimeoutFuture
类:TimeoutFuture
用法
注意:
假设玩!框架(但很容易适应)
每段代码都在同一个
ExecutionContext
中运行,这可能并不理想 .所有这些答案都需要额外的依赖性 . 我决定使用java.util.Timer编写一个版本,这是将来运行函数的有效方法,在这种情况下触发超时 .
Blog post with more details here
使用Scala的Promise,我们可以使用超时生成Future,如下所示:
Play框架包含Promise.timeout,因此您可以编写如下代码
您可以在等待未来时指定超时:
对于
scala.concurrent.Future
,result
方法允许您指定超时 .对于
scala.actors.Future
,Futures.awaitAll
允许您指定超时 .我认为Future的执行没有内置超时 .
还没有人提到
akka-streams
. 这些流有一个简单的completionTimeout方法,将其应用于单一源流就像Future一样 .但是,akka-stream也会取消,因此它实际上可以从运行中结束源,即它向源发出超时信号 .
如果您希望编写者(承诺持有者)成为控制超时逻辑的人,请按以下方式使用akka.pattern.after:
这样,如果您的承诺完成逻辑永远不会发生,那么您的调用者的未来仍将在某个时刻失败完成 .
我很惊讶这不是Scala的标准 . 我的版本很短,没有依赖关系
用法示例
Monix
Task
已超时support我正在使用这个版本(基于上面的Play示例),它使用Akka系统调度程序: