You build your computations as values, and how you build values tell you how it will be used:
eventPublisher.publish(someData)
.retry(Schedule.recurs(5))
.fold(
_ => ZIO.succeed(logger.error(s"Publishing failed")),
_ => ZIO.succeed(logger.info(s"Publishing succeeded"))
) // IO[IO[PublishError, Unit]]
is the same as (referential transparency)
val retriedPublish = eventPublisher.publish(someData).retry(Schedule.recurs(5))
retriedPublish.fold(
_ => ZIO.succeed(logger.error(s"Publishing failed")),
_ => ZIO.succeed(logger.info(s"Publishing succeeded"))
)
so I would expect it to log once, after (at most) 5 attempts. To achieve the opposite I would apply the operations in reverse order (something like)
eventPublisher.publish(someData)
.fold(
_ => ZIO.succeed(logger.error(s"Publishing failed")),
_ => ZIO.succeed(logger.info(s"Publishing succeeded"))
) // IO[IO[PublishError, Unit]] !!!
.flatten
.retry(Schedule.recurs(5))
This is same as (again referential transparency)
val loggedPublish = eventPublisher.publish(someData)
.fold(
_ => ZIO.succeed(logger.error(s"Publishing failed")),
_ => ZIO.succeed(logger.info(s"Publishing succeeded"))
)
.flatten
loggedPublish.retry(Schedule.recurs(5))
Your .fold
however recovers errors so we should so something like this to obtain the expected behavior (not loosing failure information)
eventPublisher.publish(someData)
.fold(
error => ZIO.succeed(logger.error(s"Publishing failed")) andThen ZIO.fail(error),
_ => ZIO.succeed(logger.info(s"Publishing succeeded"))
)
.flatten
.retry(Schedule.recurs(5))
// whether you want to recover after 5 failures is up to you
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…