如何缩小 ZIO Schedule 环境?
How to narrow down ZIO Schedule environment?
有一个简单的 API 示例,它使用 ZIO 效果 return None
或 Option[String]
。我用ZIO Schedule来运行效果只要None
被returned,但是有一定的次数限制。该示例基于 ZIO usecases_scheduling:
中的代码
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)
我想通过提供 Random
环境来移除 ScheduleUtil.schedule
对 Random
的依赖,并接收效果 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
方法提供什么参数?
错误消息告诉您您试图传递给函数 provide
Random.type
在行中:
RecordAPI.getRecordId.repeat(ScheduleUtil.schedule.provide(Random))
Random
作为 type 传递,但 provide
期望 instance of 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)
)
有一个简单的 API 示例,它使用 ZIO 效果 return None
或 Option[String]
。我用ZIO Schedule来运行效果只要None
被returned,但是有一定的次数限制。该示例基于 ZIO usecases_scheduling:
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)
我想通过提供 Random
环境来移除 ScheduleUtil.schedule
对 Random
的依赖,并接收效果 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
方法提供什么参数?
错误消息告诉您您试图传递给函数 provide
Random.type
在行中:
RecordAPI.getRecordId.repeat(ScheduleUtil.schedule.provide(Random))
Random
作为 type 传递,但 provide
期望 instance of 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)
)