nl.grons.sentries.core

AdaptiveThroughputSentry

class AdaptiveThroughputSentry extends ChainableSentry

A sentry that adapts throughput with the success ratio of invoking the protected resource. Think of it as a gradual circuit breaker.

The goal of this sentry is to protect the caller from a resource that slows down, or starts to produce errors when overloaded. By reducing throughput until success ratio is at an expected level, the resource can recover and work at its optimal efficiency.

For resources that behave correct most of the time, the target success ratio can be set quite high, e.g. 0.95. When exceptions are more 'normal', you may have to lower this parameter.

The success ratio is calculated per evaluationDelay with a simple 1 - (fail count / success count). When the success ratio is below targetSuccessRatio, the throughput is reduced to currentSuccessRatio * currentThroughputRatio. When the success ratio is again equal to or above the target ratio, throughput is increased by successIncreaseFactor (defaults to +20%) with a minimum of 0.0001D (1 in thousand calls may proceed). Note that regardless of the currentThroughputRatio, at least 1 call per evaluation period is allowed to continue.

This sentry only makes sense for high volume resources. To prevent throttling in low volume times, it is possible to set the minimum number of invocations that must be observed per evaluationDelay before throttling takes place. (see the minimumInvocationCountThreshold parameter).

It does not make sense to throttle on fast failing invocations. In those cases its better to get the exception from the underlying resource then to get a ReducedThroughputException. Parameter failedInvocationDurationThreshold sets the minimum duration of failed invocation in order for those invocations to be counted as failed. By setting this value to a non-zero value, fast failures do not reduce throughput. (Note that the default is 0 for backward compatibility.)

When there is a calamity, this sentry only reacts as fast as the given evaluationDelay (1 second by default). When the resource becomes fully available, it takes at most 39 evaluation before throughput is back at 100%. You can test this by evaluating the following code in a Scala REPL:

scala> val successIncreaseFactor = 1.2D
successIncreaseFactor: Double = 1.2

scala> Stream.iterate(0.0D)(x => (x * successIncreaseFactor).max(0.001).min(1.0D)).zipWithIndex.takeWhile(_._1 < 1.0).last._2 + 1
res0 Int = 39

A new instance can be obtained through the nl.grons.sentries.SentrySupport mixin.

Linear Supertypes
Ordering
  1. Alphabetic
  2. By inheritance
Inherited
  1. AdaptiveThroughputSentry
  2. ChainableSentry
  3. NamedSentry
  4. Sentry
  5. AnyRef
  6. Any
  1. Hide All
  2. Show all
Learn more about member selection
Visibility
  1. Public
  2. All

Instance Constructors

  1. new AdaptiveThroughputSentry(owner: Class[_], resourceName: String, targetSuccessRatio: Double = 0.95D, evaluationDelay: FiniteDuration = Duration(1, TimeUnit.SECONDS), minimumInvocationCountThreshold: Int = 0, successIncreaseFactor: Double = 1.2D, failedInvocationDurationThreshold: FiniteDuration = Duration(0, TimeUnit.MILLISECONDS))

    owner

    the owner class of this sentry

    resourceName

    name of the resource

    targetSuccessRatio

    target success ratio, 0 < targetSuccessRatio < 1, defaults to 0.95D

    evaluationDelay

    the time between calculations of the current throughput, defaults to 1 second

    minimumInvocationCountThreshold

    the minimum number of invocations that must be observed per evaluationDelay before invocations are throttled, defaults to 0 (>=0)

    successIncreaseFactor

    factor to apply to current throughput ratio, successIncreaseFactor > 1, defaults to 1.2D

    failedInvocationDurationThreshold

    the minimum duration for a failed invocation to be counted as failed, for backward compatibility this defaults to 0 milliseconds. A better default would be a small number, e.g. 1 millisecond.

Value Members

  1. final def !=(arg0: Any): Boolean

    Definition Classes
    AnyRef → Any
  2. final def ##(): Int

    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean

    Definition Classes
    AnyRef → Any
  4. def andThen(s: Sentry): Sentry

    Composes two instances of Sentry in a new Sentry, with this sentries context applied first.

    Composes two instances of Sentry in a new Sentry, with this sentries context applied first.

    returns

    a new sentry t such that t(x) == s(this(x))

    Definition Classes
    Sentry
  5. def apply[T](r: ⇒ T): T

    Run the given code block in the context of this sentry, and return its value.

    Run the given code block in the context of this sentry, and return its value.

    Definition Classes
    AdaptiveThroughputSentrySentry
  6. final def asInstanceOf[T0]: T0

    Definition Classes
    Any
  7. def clone(): AnyRef

    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  8. def compose(s: Sentry): Sentry

    Composes two instances of Sentry in a new Sentry, with this sentries context applied last.

    Composes two instances of Sentry in a new Sentry, with this sentries context applied last.

    returns

    a new sentry t such that t(x) == this(s(x))

    Definition Classes
    Sentry
  9. final def eq(arg0: AnyRef): Boolean

    Definition Classes
    AnyRef
  10. def equals(arg0: Any): Boolean

    Definition Classes
    AnyRef → Any
  11. val evaluationDelay: FiniteDuration

    the time between calculations of the current throughput, defaults to 1 second

  12. def failRatio: Double

    The current fail ratio (0 <= ratio <= 1).

  13. val failedInvocationDurationThreshold: FiniteDuration

    the minimum duration for a failed invocation to be counted as failed, for backward compatibility this defaults to 0 milliseconds.

    the minimum duration for a failed invocation to be counted as failed, for backward compatibility this defaults to 0 milliseconds. A better default would be a small number, e.g. 1 millisecond.

  14. def finalize(): Unit

    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] )
  15. final def getClass(): Class[_]

    Definition Classes
    AnyRef → Any
  16. def hashCode(): Int

    Definition Classes
    AnyRef → Any
  17. final def isInstanceOf[T0]: Boolean

    Definition Classes
    Any
  18. val minimumInvocationCountThreshold: Int

    the minimum number of invocations that must be observed per evaluationDelay before invocations are throttled, defaults to 0 (>=0)

  19. final def ne(arg0: AnyRef): Boolean

    Definition Classes
    AnyRef
  20. final def notify(): Unit

    Definition Classes
    AnyRef
  21. final def notifyAll(): Unit

    Definition Classes
    AnyRef
  22. def reset(): Unit

    Go back to the initial state.

    Go back to the initial state.

    Definition Classes
    AdaptiveThroughputSentrySentry
  23. val resourceName: String

    name of the resource

    name of the resource

    Definition Classes
    AdaptiveThroughputSentryNamedSentry
  24. val sentryType: String

    returns

    a simple describing identifier that is unique per sentry chain, e.g. "rateLimit". ResourceName plus sentryType uniquely name each sentry. The sentry registry enforces this. The sentryType is also used in JMX to uniquely name bean properties for a resource. null for sentry wrappers, that must not be registered.

    Definition Classes
    AdaptiveThroughputSentryChainableSentry
  25. final def synchronized[T0](arg0: ⇒ T0): T0

    Definition Classes
    AnyRef
  26. val targetSuccessRatio: Double

    target success ratio, 0 < targetSuccessRatio < 1, defaults to 0.95D

  27. def throughputRatio: Double

    The current throughput ratio (0 <= ratio <= 1).

  28. def toString(): String

    Definition Classes
    AnyRef → Any
  29. def trip(): Unit

    Reduce throughput to 0.

  30. final def wait(): Unit

    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  31. final def wait(arg0: Long, arg1: Int): Unit

    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  32. final def wait(arg0: Long): Unit

    Definition Classes
    AnyRef
    Annotations
    @throws( ... )

Inherited from ChainableSentry

Inherited from NamedSentry

Inherited from Sentry

Inherited from AnyRef

Inherited from Any

Ungrouped