重试返回Future的函数 [英] Retry a function that returns a Future

查看:94
本文介绍了重试返回Future的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个函数 foo ,该函数执行异步计算并返回 Future

Suppose I've got a function foo that performs asynchronous computation and returns a Future:

def foo(x: Int)(implicit ec: ExecutionContext): Future[Int] = ???

现在我想重试此计算 n 次直到计算成功。

Now I'd like to retry this computation n times until the computation succeeds.

def retryFoo(x: Int, n: Int)(implicit ec: ExecutionContext): Future[Int] = ???

我还要返回重试时抛出的所有 all 异常。因此,我定义了新的异常类 ExceptionsList 并要求 retryFoo 返回 ExceptionsList 当所有重试均失败时。

I would like also to return all exceptions thrown while retrying. So, I define new exception class ExceptionsList and require retryFoo to return ExceptionsList when all retries fail.

case class ExceptionsList(es: List[Exception]) extends Exception { ... }  

您如何编写 retryFoo 重试 foo 并返回 Future foo 结果或 ExceptionsList

How would you write retryFoo to retry foo and return a Future with either the foo result or ExceptionsList ?

推荐答案

我可能会做这样的事情:

I'd probably do something like this:

final case class ExceptionsList(es: List[Throwable]) extends Throwable
def retry[T](n: Int, expr: => Future[T], exs: List[Throwable] = Nil)(implicit ec: ExecutionContext): Future[T] =
  Future.unit.flatMap(_ => expr).recoverWith {
    case e if n > 0 => retry(n - 1, expr, e :: exs)
    case e => Future.failed(new ExceptionsList(e :: exs))
  }

expr 是按名称调用的,因为它本身可能引发异常,而不是返回失败的Future。我将累积的例外记录在列表中,但我想那是一种味道。

expr is call-by-name since it itself could throw an exception rather than returning a failed Future. I keep the accumulated exceptions in a list, but I guess that's a taste-thing.

这篇关于重试返回Future的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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