Scala – 在 futures 的 for 推导中进行重试(SoftwareMill 重试)

huangapple go评论61阅读模式
英文:

Scala - Retry on a for comp of futures (SoftwareMill Retry)

问题

我有一些代码,试图在for推导中执行一系列的未来任务,并返回推导完成的值。我想在整个for推导中实现一个重试函数,而不是在每个嵌套的未来任务上实现单独的重试。我尝试使用[SoftwareMill的Retry][1]。

示例代码:

```scala
  implicit val successDeterminer: Success[Either[Error, Option[FinalResponse]]] =
    Success[Either[Error, Option[FinalResponse]]](
      test => test.isRight
    )

    def processExample(var1: Variable1, var2: Variable2): Future[Either[Error, SuccessfulResponse]] = {
    val result = for {
      resp1 <- function1(var1) // 返回 EitherT[Future, Error, Response1]
      resp2 <- function2(var2) // 返回 EitherT[Future, Error, Response2]
      doesSomething = function3(resp2) // 返回 boolean
      finalResult <- function4(doesSomething) // 返回 EitherT[Future, Error, Option[FinalResponse]
    } yield finalResult

    val retryResult = policy.apply(() => result.value)(
      success = successDeterminer,
      executor = executionContext
    )
    handleRetriedResult(retryResult) // 返回 Future[Either[Error, Option[SuccessfulResponse]]
  }

所以这个运行了,但我有一个单元测试强制使function2返回一个Left响应。因此,根据我的策略,我期望此重试执行3次。然而,它只执行了对function2的调用一次。

是否不可能将重试放在整个for推导上,并使其重试整个操作流程?如果我希望它们全部重试,是不是需要将其放在每个单独的未来任务上?


<details>
<summary>英文:</summary>

I have some code that attempts to execute a series of futures within a for comp and returns the value of the completion of the comp. I want to implement a retry function on the entirety of the for comp, rather than implementing an individual retry on each of the nested futures.  I&#39;m trying to use [SoftwareMill&#39;s Retry][1]

Example code:

implicit val successDeterminer: Success[Either[Error, Option[FinalResponse]]] =
Success[Either[Error, Option[FinalResponse]]](
test => test.isRight
)

def processExample(var1: Variable1, var2: Variable2): Future[Either[Error, SuccessfulResponse]] = {
val result = for {
  resp1 &lt;- function1(var1) //returns EitherT[Future, Error, Response1]
  resp2 &lt;- function2(var2) // returns EitherT[Future, Error, Response2]
  doesSomething = function3(resp2) // returns boolean
  finalResult &lt;- function4(doesSomething) // returns EitherT[Future, Error, Option[FinalResponse]
} yield finalResult

val retryResult = policy.apply(() =&gt; result.value)(
  success = successDeterminer,
  executor = executionContext
)
handleRetriedResult(retryResult) // returns Future[Either[Error, Option[SuccessfulResponse]]

}


So this runs, but I have a unit test that forces function2 to return a Left response.  Therefore, I expect this retry to execute 3 times based on my policy.  However, it only executes the call to function2 once.

Is it not possible to put the retry on the entire for comp and have it retry the entire flow of operations?  Do I need to put it on each individual future that I have if I want them all to retry?  


  [1]: https://github.com/softwaremill/retry

</details>


# 答案1
**得分**: 1

这总是发生。一旦我发布一个问题,它就会点击。所以问题是`for comp`被定义为函数调用内的一个变量。所以当重试发生时,它正在重试那个已经执行了`for comp`的变量,因此具有一个值。它不需要重新调用内部的未来。

通过将我的`for comp`代码移动到自己的函数中,然后让重试调用该函数,当它重试时,它会创建一个全新的`for comp`未来调用,因此执行我想要的次数。

<details>
<summary>英文:</summary>

This always happens.  As soon as I post a question it ends up clicking.  So the problem is that the for comp is being defined as a variable inside the function call.  So when the retry happens, its retrying that variable which already executed the for comp and therefore has a value.  It doesn&#39;t need to recall the futures inside.

By moving my for comp code into its own function, and then having the retry call that function instead, when it retries it is creating a brand new call of my for comp future and therefore executing the number of times I want.

</details>



huangapple
  • 本文由 发表于 2023年6月30日 01:07:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76583208.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定