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

com.twitter.zk.RetryPolicy.scala Maven / Gradle / Ivy

There is a newer version: 6.38.0
Show newest version
package com.twitter.zk

import org.apache.zookeeper.KeeperException

import com.twitter.conversions.time._
import com.twitter.util.{Duration, Future, Timer}

/** Pluggable retry strategy. */
trait RetryPolicy {
  def apply[T](op: => Future[T]): Future[T]
}

/** Matcher for connection-related KeeperExceptions. */
object KeeperConnectionException {
  def unapply(e: KeeperException) = e match {
    case e: KeeperException.ConnectionLossException => Some(e)
    case e: KeeperException.SessionExpiredException => Some(e)
    case e: KeeperException.SessionMovedException => Some(e)
    case e: KeeperException.OperationTimeoutException => Some(e)
    case e => None
  }
}

object RetryPolicy {
  /** Retries an operation a fixed number of times without back-off. */
  case class Basic(retries: Int) extends RetryPolicy {
    def apply[T](op: => Future[T]): Future[T] = {
      def retry(tries: Int): Future[T] = {
        op rescue { case KeeperConnectionException(_) if (tries > 0) =>
          retry(tries - 1)
        }
      }
      retry(retries)
    }
  }

  /**
   *  Retries an operation indefinitely until success, with a delay that increases exponentially.
   *
   *  @param base   initial value that is multiplied by factor every time; should be > 0
   *  @param factor should be >= 1 so the retries do not become more aggressive
   */
  case class Exponential(
    base: Duration,
    factor: Double = 2.0,
    maximum: Duration = 30.seconds
  )(implicit timer: Timer) extends RetryPolicy {
    require(base > 0.seconds)
    require(factor >= 1)

    def apply[T](op: => Future[T]): Future[T] = {
      def retry(delay: Duration): Future[T] = {
        op rescue { case KeeperConnectionException(_) =>
          timer.doLater(delay) {
            retry((delay.inNanoseconds * factor).toLong.nanoseconds min maximum)
          }.flatten
        }
      }
      retry(base)
    }
  }

  /** A single try */
  object None extends RetryPolicy {
    def apply[T](op: => Future[T]) = op
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy