All Downloads are FREE. Search and download functionalities are using the official Maven repository.

endless.transaction.impl.helpers.RetryHelpers.scala Maven / Gradle / Ivy

The newest version!
package endless.transaction.impl.helpers

import cats.effect.kernel.Temporal
import cats.syntax.applicativeError.*
import cats.syntax.apply.*
import cats.syntax.flatMap.*
import scala.concurrent.duration.*

object RetryHelpers {
  final case class RetryParameters(initialDelay: Duration, maxRetries: Int)

  trait OnError[F[_]] {
    def apply(error: Throwable, delay: Duration, retryAttempt: Int, maxRetries: Int): F[Unit]
  }

  implicit class RetryOps[F[_], A](fa: F[A]) {
    def retryWithBackoff(
        onError: OnError[F]
    )(implicit retryParameters: RetryParameters, temporal: Temporal[F]): F[A] = {
      import retryParameters.*
      retryWithBackoffImpl(onError, initialDelay, retryAttempt = 0, maxRetries)
    }

    private def retryWithBackoffImpl(
        onError: OnError[F],
        delay: Duration,
        retryAttempt: Int,
        maxRetries: Int
    )(implicit temporal: Temporal[F]): F[A] = {
      fa.handleErrorWith { error =>
        if (retryAttempt < maxRetries)
          onError(error, delay, retryAttempt + 1, maxRetries) *> temporal.sleep(
            delay
          ) >> retryWithBackoffImpl(onError, delay * 2, retryAttempt + 1, maxRetries)
        else temporal.raiseError(error)
      }
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy