true
またはを返す IO (したがって安全でない) 操作があるとしますfalse
。Zio スケジューリング メカニズムを使用して、値が になるまでこれを実行したいのですがtrue
、最大 N 回までです。ドキュメントからコードを採用し、それを私が達成しようとしているものに変更するには...
import zio._
import zio.duration._
import zio.console._
import zio.clock._
import java.util.Random
object API {
// our API method will return true about 30% of the time, but
// return false the rest of the time (instead of throwing an
// exception, as is shown in documentation)
def makeRequest: Task[Boolean] = Task.effect {
new Random().nextInt(10) > 7
}
}
object ScheduleUtil {
def schedule[A] = Schedule.spaced(1.second) && Schedule.recurs(4).onDecision({
case Decision.Done(_) => putStrLn(s"done trying")
case Decision.Continue(attempt, _, _) => putStrLn(s"attempt #$attempt")
})
}
import ScheduleUtil._
import API._
object ScheduleApp extends scala.App {
implicit val rt: Runtime[Clock with Console] = Runtime.default
rt.unsafeRun(makeRequest.retry(schedule).foldM(
ex => putStrLn("Exception Failed"),
v => putStrLn(s"Succeeded with $v"))
)
}
// run the app
ScheduleApp.main(Array())
もちろん、これは機能しません。出力はSucceeded with false
or (場合によっては)のいずれかSucceeded with true
です。定義に追加しようとしSchedule.recurUntilEquals
ましたが、役に立ちませんでした。Schedule
object ScheduleUtil {
def schedule[A] = Schedule.spaced(1.second) && Schedule.recurUntilEquals(true) && Schedule.recurs(4).onDecision({
case Decision.Done(_) => putStrLn(s"done trying")
case Decision.Continue(attempt, _, _) => putStrLn(s"attempt #$attempt")
})
}
import ScheduleUtil._
// re-define ScheduleApp in the exact same way as above, and the following error results:
cmd93.sc:5: polymorphic expression cannot be instantiated to expected type;
found : [A]zio.Schedule[zio.console.Console,Boolean,((Long, Boolean), Long)]
(which expands to) [A]zio.Schedule[zio.Has[zio.console.Console.Service],Boolean,((Long, Boolean), Long)]
required: zio.Schedule[?,Throwable,?]
rt.unsafeRun(makeRequest.retry(schedule).foldM(
Zio スケジューラーを使用してそのようなユースケースを達成するにはどうすればよいですか? もちろん、makeRequest
false を返す代わりに、意図的に例外をスローするようにタスクを再定義することもできます。これはドキュメントと同じように機能します。しかし、不必要な例外の生成/処理を避けたいと思っていました。
object API {
// our API method will return true about 30% of the time, but
// return false the rest of the time (instead of throwing an
// exception, as is shown in documentation)
def makeRequest = Task.effect {
if (new Random().nextInt(10) > 7) true else throw new Exception("Not true")
}
}