0

我有一个简单的代码retry在发布消息失败时执行:

eventPublisher.publish(someData)
.retry(Schedule.recurs(5))
.fold(
_ => ZIO.succeed(logger.error(s"Publishing failed")),
_ => ZIO.succeed(logger.info(s"Publishing succeeded"))
)

但我不确定它是否会在每个retry. 如果发布失败,我想在每次重试后记录“发布事件失败”。此外,我不确定retryfold我的意思是)之后的代码是否在每个retry周期后执行。

这是正确的方法还是我应该使用其他方法来达到我的需要?

4

1 回答 1

1

您将计算构建为值,而构建值的方式会告诉您如何使用它:

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]]

与(参考透明度)相同

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"))
) 

所以我希望它在(最多)5 次尝试后记录一次。为了达到相反的效果,我将以相反的顺序应用操作(类似)

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))

这与(再次引用透明度)相同

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))

但是,您.fold可以恢复错误,因此我们应该这样做以获得预期的行为(不丢失失败信息)

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
于 2021-01-12T13:33:20.690 回答