Class Delayer<T>

  • Type Parameters:
    T - The type of elements for which a delay is required.

    public class Delayer<T>
    extends Object
    A delayer provides the means to delay a call based on the amount of tries a provided element has experienced. For instance, when logging on with a fixed user name, one should delay failing authentication tries to avoid brute-force attacks. As for the authentication, a few free tries are possible to allow for misspelling without delaying. Additionally, there is an upper bound for the delay and thus also an upper bound for the time the amount of tries are remembered. As soon as the authentication (or whatever requires the delay) has been successful, the delay for the corresponding element should be reset.
    Author:
    Ulrich Kreher
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      protected class  Delayer.Resetter
      A runnable for resetting the try count and thus remove all delays.
    • Constructor Summary

      Constructors 
      Constructor Description
      Delayer​(String name, int undelayedTries)
      Creates a new delayer with the designated name and the designated amount of tries without a delay, delaying a call dependent of the element and the amount of tries for the element.
    • Field Detail

      • MAX_DELAY_PER_TRY

        protected static final long MAX_DELAY_PER_TRY
        The maximum delay per try in milliseconds. If the calculated delay exceeds this time, time will be used for delay instead of the calculated one.
        See Also:
        Constant Field Values
      • undelayedTries

        protected final int undelayedTries
        The number of tries, that are not subject of a delay.
      • pendingTries

        protected final long pendingTries
        The time in milliseconds the try count keeps pending and is not reset. If there is another try within this time after the last delay, the try count just continues. If this time elapses, the try count resets and allows tries without delay again.
        This time has to be at least the number of tries without delay multiplied with the maximum delay per try to compensate for the tries without after this time has elapsed.
      • maxDelayTry

        protected int maxDelayTry
        The amount of tries that lead to a delay just below maximum delay per try. One additional try exceeds this maximum delay.
      • tryCounts

        protected final Map<T,​Pair<AtomicInteger,​Runnable>> tryCounts
        The number of tries of an element (and the corresponding resetting runnable).

        AtomicInteger is used here since it is mutable in contrast to Integer and thus avoids the creation of numerous (immutable) Pairs.

      • resetFutures

        protected final Map<T,​ScheduledFuture<?>> resetFutures
        The futures for the resetting runnables. These need to be cancelled after a new try and the runnable needs to be rescheduled.
    • Constructor Detail

      • Delayer

        public Delayer​(String name,
                       int undelayedTries)
        Creates a new delayer with the designated name and the designated amount of tries without a delay, delaying a call dependent of the element and the amount of tries for the element.
        Parameters:
        name - The name of the delayer (used for internal scheduler thread).
        undelayedTries - The number of tries that are not subject of delay. As soon as this number is exceeded, a delay will take place.
    • Method Detail

      • delay

        public void delay​(T element)
                   throws InterruptedException
        Delays the current thread depending on the current amount of tries for the designated element needs a delay. This increases the current amount of tries for the designated element and respects the lower (the amount of tries without delay) and the upper (the maximum delay per try) bound for the delay.
        Parameters:
        element - The element for which to count a try and possibly delay.
        Throws:
        InterruptedException - If the waiting thread is interrupted while waiting for the delay, an InterruptedException will be thrown. Since this allows to circumvent the delay, callers must not ignore the interrupt but handle it appropriately for instance by shutting down.
      • reset

        public void reset​(T element)
        Resets the try count and delay for the designated element.
        Parameters:
        element - The element for which to reset the try count and the delay.
      • getDelay

        protected long getDelay​(int tryCount)
        Calculates the delay (in milliseconds) for the designated try count. The delay will be 0 for the number of tries without delay and it will not exceed the maximum delay per try.
        This implementation doubles the delay for each try.
        Parameters:
        tryCount - The amount of tries that have been used yet.
        Returns:
        The delay for the designated amount of tries.