scala 在ZIO中,如何创建一个在满足多个条件时重复尝试的时间表,分别计算每个条件的尝试次数

r8uurelv  于 5个月前  发布在  Scala
关注(0)|答案(1)|浏览(70)

我正在使用ZIO,我的任务是用这样的逻辑(简化)重试对某些服务的请求:
1.如果响应包含一些不正确的数据-重试N次,如果情况没有改变-保留结果
1.如果响应包含的数据不足-重试M次,如果情况未发生变化-保留结果
我计划使用ZIO的.repeat函数,但不知道如何编写将为每个条件单独计算重试次数的计划。

package com.mycompany

import zio.Schedule.WithState
import zio.{ExitCode, Schedule, Task, URIO, ZIO, ZIOAppDefault}

import scala.util.Random

object Main3 extends ZIOAppDefault {
  def makeRequest: Task[Float] = ZIO.attempt {
    new Random().nextFloat() * 10
  }

  def makeSchedule(): WithState[(Unit, Unit), Any, Float, Float] = {
    val firstCondition =
      Schedule.recurUntil[Float](float => float > 3)
        // TODO: make only 3 tries for this condition
        .onDecision {
          case (input, value, decision) => ZIO.log(s"FirstCondition: ${input}, ${value}, ${decision}")
        }

    val secondCondition =
      Schedule.recurUntil[Float](float => float < 9)
        // TODO: make only 5 tries for this condition
        .onDecision {
          case (input, value, decision) => ZIO.log(s"SecondCondition: ${input}, ${value}, ${decision}")
        }

    firstCondition.||(secondCondition).map(_._1)
  }

  override def run: URIO[Any, ExitCode] = {
    makeRequest
      .repeat(makeSchedule())
      .tap(res => ZIO.log(f"RESULT IS: $res"))
      .exitCode
  }
}

字符串

6ovsh4lw

6ovsh4lw1#

我找到了解决办法:

.repetitions
.whileOutput(repetition => repetition < 3)
.passthrough[Float]

字符串
调用passthrough[Float]允许对齐类型并从repeat中获取结果。最后的代码片段是

package com.mycompany

import zio.Schedule.WithState
import zio.{ExitCode, Schedule, Task, URIO, ZIO, ZIOAppDefault}

import scala.util.Random

object Main3 extends ZIOAppDefault {
 def makeRequest: Task[Float] = ZIO.attempt {
   new Random().nextFloat() * 10
 }

 def makeSchedule() = {
   val firstCondition =
     Schedule.recurUntil[Float](float => float > 8)
       .repetitions
       .whileOutput(repetition => repetition < 3)
       .passthrough[Float]
       .onDecision {
         case (input, value, decision) => ZIO.log(s"FirstCondition: ${input}, ${value}, ${decision}")
       }

   val secondCondition: WithState[(Unit, Long), Any, Float, Float] =
     Schedule.recurUntil[Float](float => float < 9)
       .repetitions
       .whileOutput(repetition => repetition < 5)
       .passthrough[Float]
       .onDecision {
         case (input, value, decision) => ZIO.log(s"SecondCondition: ${input}, ${value}, ${decision}")
       }

   firstCondition.||(secondCondition).map(_._1)
 }

 override def run: URIO[Any, ExitCode] = {
   makeRequest
     .repeat(makeSchedule())
     .tap(res => ZIO.log(f"RESULT IS: $res"))
     .exitCode
 }
}

相关问题