如何缩小ZIO时间表环境



有一个简单的API示例,它使用ZIO效果返回NoneOption[String]。只要返回None,我就会使用ZIO Schedule来运行效果,但次数有限。该示例基于ZIO用例_调度:中的代码

import zio._
import zio.random._
import zio.duration._
import zio.console.{Console, putStrLn}
import zio.Schedule
import scala.util.{Random => ScalaUtilRandom}
object RecordAPI {
def randomId(length: Int): String =
LazyList.continually(ScalaUtilRandom.nextPrintableChar).filter(_.isLetterOrDigit).take(length).mkString
def getRecordId: Task[Option[String]] = Task.effect(
if (ScalaUtilRandom.nextInt(10) >= 7) Some(randomId(16)) else None
)
}
object ScheduleUtil {
def schedule[A]: Schedule[Random, Option[String], Option[String]] =
(Schedule.exponential(10.milliseconds) && Schedule.recurs(10)) *> Schedule.recurWhile(_.isEmpty)
}
object RandomScheduler extends scala.App {
implicit val rt: Runtime[zio.ZEnv] = Runtime.default
rt.unsafeRun {
RecordAPI.getRecordId
.repeat(ScheduleUtil.schedule)
.foldM(
ex => putStrLn(s"failed with ${ex.getMessage}"),
success => putStrLn(s"Succeeded with $success")
)
}
}

以下效果的类型为ZIO[Random with clock.Clock, Throwable, Option[String]]:

RecordAPI.getRecordId.repeat(ScheduleUtil.schedule)

我想通过提供Randomenv来消除ScheduleUtil.scheduleRandom的依赖,并接收效果ZIO[Any with clock.Clock, Throwable, Option[String]]:

RecordAPI.getRecordId.repeat(ScheduleUtil.schedule.provide(Random))

但我得到编译错误:

[error]  found   : zio.random.Random.type
[error]  required: zio.random.Random
[error]     (which expands to)  zio.Has[zio.random.Random.Service]
[error]       .repeat(ScheduleUtil.schedule.provide(Random))
[error]                                             ^
[error] one error found

.provide方法应提供什么参数?

错误消息告诉您试图传递给函数provideRandom.type行中:

RecordAPI.getRecordId.repeat(ScheduleUtil.schedule.provide(Random))

Random作为类型传递,但provide期望Random实例。因此,只需将Random类型替换为一些它的实例即可使代码可编译:

val hasRandomService: Random = Has.apply(Random.Service.live)
val randomIdZIO: ZIO[Random, Throwable, Option[String]] = 
RecordAPI.getRecordId.repeat(ScheduleUtil.schedule.provide(hasRandomService))

但如果你想摆脱ScheduleUtil.schedule,也许最好使用Schedule.fromFunction函数:

val randomIdZIOFromFunction: ZIO[Random, Throwable, Option[String]] = 
RecordAPI.getRecordId.repeat(
Schedule.fromFunction(_ => if (ScalaUtilRandom.nextInt(10) >= 7) Some(randomId(16)) else None)
)

相关内容

  • 没有找到相关文章

最新更新