gpt4 book ai didi

具有 Future 返回类型的 Scala 递归函数

转载 作者:行者123 更新时间:2023-12-02 15:03:12 25 4
gpt4 key购买 nike

我正在 scala 中编写一个递归重试函数,我想知道 future 的创建是否存在运行时错误。如果存在则重试 future 的实例化。

假设我有一个数据库查询功能:

dbLookup(userId : UserId) : Option[UserName] = ???

重试的形式如下:

retry[T](f : () => Future[Option[T]],  
notifyFailure : (t : Throwable) => Unit,
n : Int) : Future[Option[T]] = {
if(n <= 0) { Future{None} }
else {
val fut = f()
if(f.resultsInException) { //I don't know how to write this
notifyFailure(f.exception)
retry(f, notifyFailure, n-1) //try again
}
else {
f.originalValueAsFuture
}
}
}

如何实现这一 future 功能并允许尾递归优化?

如果当我尝试创建 Future 时执行上下文不断抛出异常,则可以使用此函数为用户重试数据库 10 次:

val userNameAfterRetries = 
retry(() => Future{dbLookup("1234")},
(t) => system error (s"future creation error : $t"),
10)

注意:这在 Future.fallbackTo 中是可能的,但不幸的是,fallbackTo 接受的是 Future[T] 而不是 () => Future [T]。这很重要,因为即使第一次尝试成功,使用 FallbackTo 也会导致至少重试 1 次。

预先感谢您的考虑和回复。

最佳答案

这个怎么样?

  def retry[T](f: () => Future[Option[T]],
notifyFailure: Throwable => Unit,
n: Int)(implicit ec : ExecutionContext): Future[Option[T]] = {
if (n <= 0) Future.failed(new RuntimeException("Exceeded number of allowed retries"))
else f().recoverWith { case originalError => notifyFailure(originalError); retry(f, notifyFailure, n - 1) }
}

尾递归更新:Future的本质是异步的,所以除非你想等待结果,我不太明白它可以将其设为@tailrec,因为您必须在回调中使用递归。

还有实用说明:如果你知道它总是~10次重试,我就不会害怕递归。

关于具有 Future 返回类型的 Scala 递归函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40177970/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com