我正在尝试弄清楚如何惯用地使用 zio.Schedule。我看到它有状态、输入和输出,但不明白如何使用它们。
例如,假设我有一个实用函数,它不断尝试对给定的时间表产生某种影响,直到成功:
def keepTrying[A])(f: Task[A])(policy: Schedule[Any, Any, Any]: Promise[A] = for {
promise <- Promise.make[Throwable, A]
_ <- f.retry(policy)
.flatMap(promise.succeed)
.unit
.forkDaemon
} yield promise
我认为这可行(是吗?)...但是,如果我想修改此函数以记录其尝试以及迄今为止的失败和尝试次数的信息,例如
log(s"Retry #$n failed with $error")
执行此操作的惯用方法是什么?是否可以以某种方式操纵
policy
在每次尝试后获得包含此信息的回调?
您可以使用
tapOutput
的Schedule
:
val policy: Schedule[Any, Any, T] = ???
val policyWithLogs: Schedule[Any, Any, T] = policy.tapOutput { t: T =>
ZIO.log("Retrying...")
}
但是,这要求您的
Schedule
中有一个包含一些有用数据的“输出”类型。
开箱即用的政策就是这种情况:
Schedule.recurs(...) // Schedule[Any, Any, Long]
Schedule.exponential(...) // Schedule[Any, Any, Duration]