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

com.ing.baker.recipe.common.InteractionFailureStrategy.scala Maven / Gradle / Ivy

There is a newer version: 1.1.18
Show newest version
package com.ing.baker.recipe.common

import com.ing.baker.recipe.common

import scala.annotation.tailrec
import scala.concurrent.duration.Duration

sealed trait InteractionFailureStrategy

object InteractionFailureStrategy {

  case class BlockInteraction() extends InteractionFailureStrategy

  case class FireEventAfterFailure(event: common.Event) extends InteractionFailureStrategy

  case class RetryWithIncrementalBackoff(initialTimeout: Duration,
                                         backoffFactor: Double,
                                         maximumRetries: Int,
                                         maxTimeBetweenRetries: Option[Duration] = None,
                                         retryExhaustedEvent: Option[common.Event] = None) extends InteractionFailureStrategy {
    require(backoffFactor >= 1.0, "backoff factor must be greater or equal to 1.0")
    require(maximumRetries >= 1, "maximum retries must be greater or equal to 1")
  }

  object RetryWithIncrementalBackoff {
    def apply(initialDelay: Duration,
              deadline: Duration,
              maxTimeBetweenRetries: Option[Duration],
              exhaustedEvent: Option[common.Event]): RetryWithIncrementalBackoff = {

      require(deadline > initialDelay, "deadline should be greater then initialDelay")

      val backoffFactor = 2.0

      @tailrec def calculateMaxRetries(lastDelay: Duration,
                                       backoffFactor: Double,
                                       deadline: Duration,
                                       totalDelay: Duration,
                                       timesCounter: Int): Int = {

        def min(d1Option: Option[Duration], d2: Duration): Duration = d1Option match {
          case Some(d) if d < d2 => d
          case _ => d2
        }

        val nextDelay = min(maxTimeBetweenRetries, lastDelay * backoffFactor)

        if ((totalDelay + nextDelay) > deadline) timesCounter
        else calculateMaxRetries(nextDelay, backoffFactor, deadline, totalDelay + nextDelay, timesCounter + 1)
      }

      new RetryWithIncrementalBackoff(
        initialTimeout = initialDelay,
        backoffFactor,
        maximumRetries = calculateMaxRetries(
          lastDelay = initialDelay,
          backoffFactor,
          deadline,
          totalDelay = initialDelay,
          timesCounter = 1),
        maxTimeBetweenRetries,
        exhaustedEvent)
    }
  }

}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy