如何安全地对Scala Future进行重试?

时间:2016-02-25 00:40:34

标签: scala future

我有一些启动“慢”过程的代码,我将其包装在Future中。如果出现问题,我想慢慢循环并在暂停后重试 - 无限期。有点像这样:(我知道人类最终会介入并解决问题)

(Monad m, Redis m) => ...

当调用onComplete回调时,doSomething()是否仍然在堆栈上或者是否已经弹出,因为我们在Future执行慢速任务(aFutureThing)时返回了?这个递归调用doSomething(最终)会炸毁堆栈/ OutOfMemory还是什么?如果是这样......有没有更安全的方式对未来进行重试?

1 个答案:

答案 0 :(得分:3)

这里没有递归。 doSomething将创建Future并立即返回,而Future被提交以在另一个线程上执行(如果它是池的一部分,它实际上可能在同一个线程上执行,但是不是在doSomething返回之前。

您可以通过在repl:

中运行类似的内容来自行查看
def foo(n: Int): Future[Int] = Future {
   Thread.sleep(1000)
   if(n < 10) throw new IllegalArgumentException(); else n 
} recoverWith { case e => 
   e.printStackTrace();
   println("N was " + n)
   Thread.sleep(1000)
   println("Rinse and repeat!")
   foo(n+1)
}

foo(1)

它会&#34;重试&#34;在实际成功之前9次,并且每次都打印异常的堆栈,这样你就可以看到回溯是相同的,它们不会增长,因为没有递归。