hq/app/logic/Retry.scala (19 lines of code) (raw):

package logic import utils.attempt.{Attempt, Failure} import scala.concurrent.ExecutionContext import scala.concurrent.duration.FiniteDuration object Retry { /** * execute the body until the predicate is satisfied or maxAttempt is reached, with the delay between each body execution. */ def until[A](body: => Attempt[A], predicate: A => Boolean, failureMessage: String, delay: FiniteDuration, maxAttempt: Int = 10)(implicit ec: ExecutionContext): Attempt[A] = { def loop(numberOfTries: Int): Attempt[A] = { if (numberOfTries >= maxAttempt) { Attempt.Left[A](Failure(s"MAX_ATTEMPT_LIMIT_REACHED: $failureMessage", failureMessage, 500)) } else { for { result <- if (numberOfTries == 0) body else body.delay(delay) next <- if (predicate(result)) Attempt.Right(result) else loop(numberOfTries + 1) } yield next } } loop(0) } }