关于期货与期货的结合有很多问题。说实话,我还没有完全理解如何使用它们。但似乎我偶然发现了一个我必须(或许不是)的问题。
如果语句超过1分钟,我想抛出一个TimeoutException
。要更清楚,目前,此语句尝试从服务器获取响应,但如果服务器未设置则不会抛出。它目前看起来像这样:
//proper import of exceptions
case class ServerException(exception: Throwable) extends Exception(exception)
//Code that instantiates client and post
val response = try {
client.execute(post)
} catch {
case e@(_: IOException | _: ClientProtocolException) => throw new ServerException(e)
}
为了缓解这个问题,我想引入一个超时。如何在此语句中引入超时,以便在一分钟内没有响应时抛出,否则它实例化response
并且程序继续保持原样?
答案 0 :(得分:0)
scala Futures不具备此功能。你可以切换到scalaz任务 - 它对于异步/延迟计算有点不同的抽象。您可以在此处阅读有关它的精彩文档:http://timperrett.com/2014/07/20/scalaz-task-the-missing-documentation/
import java.util.concurrent.Executors
import scalaz.concurrent.Task
import scala.concurrent.duration._
implicit val scheduledThreadPool =
Executors.newScheduledThreadPool(5)
def executeRequest(req: Request): Task[Response] = ???
val withTimeOut: Task[Response] =
executeRequest(req).timed(1.minute)
<强>更新强>
顺便说一下,您可以轻松地将Future转换为Task,例如Future来自第三方lib
object Future2Task {
implicit class Transformer[+T](fut: => Future[T]) {
def toTask(implicit ec: scala.concurrent.ExecutionContext): Task[T] = {
import scala.util.{Failure, Success}
import scalaz.syntax.either._
Task.async {
register =>
fut.onComplete {
case Success(v) => register(v.right)
case Failure(ex) => register(ex.left)
}
}
}
}
}
答案 1 :(得分:0)
超时通常通过将异步计时器作为超时信号并在计时器完成时完成将来的任务来实现。
我相信Akka有一个这样的计时器,但推出自己的计时器非常简单:
object ConcurrencyUtil {
// creates a Future that will complete after a specified duration
object Delay {
def apply(d: Duration): Future[Unit] = {
val p = Promise[Unit]()
val t = new Timer
t.schedule(new TimerTask {
override def run(): Unit = p.success()
}, d.toMillis)
p.future
}
}
implicit class FutureExtensions[T](future: Future[T]) {
def timeout(timeout: Duration) = Future.firstCompletedOf(Seq(
Delay(timeout).map(_ => throw new TimeoutException()),
future
))
}
}
现在你可以像以下一样为你的未来撰写timeout
:
import ConcurrencyUtil._
val f = someTaskReturningAFuture.timeout(1.minute)
现在,如果任务未在1分钟内完成,则延迟将触发,映射为抛出TimeoutException
并完成将来f
失败。
注意:这不会解决取消,即另一个未来,而不再被听取将继续存在,如果它正在执行某些事情,继续执行。