`akka.pattern.after` - 理解`持续时间`参数?

时间:2016-11-21 16:05:31

标签: scala akka

使用Scala 2.11.8,假设Future在返回5之前休眠()秒,我调用akka.pattern.ask时超时{{1}第二:

1

为什么import scala.concurrent.duration._ import scala.concurrent._ import akka.actor.ActorSystem import scala.concurrent.ExecutionContext.Implicits.global import akka.pattern.after val system = ActorSystem.create() after( FiniteDuration(1, SECONDS), system.scheduler)( Future{ Thread.sleep( 5000 ); () } ) res15: scala.concurrent.Future[Unit] = List() // roughly 5 seconds later, I see: scala> res15 res22: scala.concurrent.Future[Unit] = Success(()) 没有res15返回Failure,因为Future在5秒内没有完成,但是超时为1秒?

1 个答案:

答案 0 :(得分:3)

After方法会在延迟一段时间后运行您的未来。 duration不是超时,它是启动延迟。 After方法在内部使用了actorSystem schedular的scheduleOnce方法。

After是一种非常有趣的方法,它只在特定的持续时间后开始评估/执行你的未来表达式(即value)。

如果给定的持续时间非常小,那么它会立即开始执行value

由于value是按名称参数调用,因此不会立即评估该值。只有在通过名称值显式调用时才会评估value

以下是akka lib的代码。

def after[T](duration: FiniteDuration, using: Scheduler)(value: ⇒ Future[T])(implicit ec: ExecutionContext): Future[T] =
  if (duration.isFinite() && duration.length < 1) {
    try value catch { case NonFatal(t) ⇒ Future.failed(t) }
  } else {
   val p = Promise[T]()
   using.scheduleOnce(duration) { p completeWith { try value catch { case NonFatal(t) ⇒ Future.failed(t) } } }
   p.future
}

基本上你的持续时间会触发以下代码

using.scheduleOnce(duration) { p completeWith { try value catch { case NonFatal(t) ⇒ Future.failed(t) } } }

上述代码将在延迟后开始执行未来(duration是延迟。)。

重要观察:

请注意,value是按名称参数调用的。当按名称调用时,将评估value,这意味着除非显式调用value,否则将来不会开始执行。 value在try中被调用,因为value可能是一个包含大量代码并最终返回未来的多行表达式。

Promise(参见代码)会让你以非阻塞的方式等待,直到将来完成执行。 promise.future只有在未来完成时才会完成。