Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

apache kafka - Scala, ZIO - log something after every retry

I have a simple code which do retry when publishing message failed:

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

But I am not sure if it would log error after every retry. I would like to log "Publishing event failed" after every retry if publishing failed. Also I am not sure if the code after retry (fold one I mean) is performed after every retry cycle.

Is it correct approach or I should use something else to reach what I need?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...