Class AdjustableCallback

java.lang.Object
com.tccc.kos.commons.util.concurrent.BaseCallback
com.tccc.kos.commons.util.concurrent.AdjustableCallback

public class AdjustableCallback extends BaseCallback
Class that supports single (one-shot) or recurring callbacks, allows the delay to be adjusted while the timer is running, and has variance support to add a degree of randomness to the timer. This class guarantees that the callback is never called concurrently, even if a timer is stopped and restarted or called inline while an existing callback is being performed.

A timer is started as either recurring or non-recurring, and recurring mode can be toggled while the timer is running. Once the timer fires in non-recurring mode, it never fires again. However, if the timer is then re-started, the current recurring mode remains in effect.

When setting the delay for a timer, there are two methods that behave slightly differently:

  • setDelay() : If the timer is not running, the delay value is used as the new delay value. If the timer is running, then the amount of wait time on the current timer is deducted from the delay for the first cycle of the timer. The intention is that if a timer was set to 60 minutes and the timer has already waited 45 minutes and the delay is then changed to 15 minutes, the timer has already waited long enough to trigger from a real world perspective. This is typically desirable behavior so that QA can shorten timers for testing and not have to wait excessively for the first cycle. This is also useful for operations when adjusting settings on live equipment.
  • setAbsDelay() : The delay is always treated as absolute.
This timer also supports variances which are used to introduce variability into the effective delays. Variability is generally used when interacting with external systems, as timer-based clients tend to synchronize over time and cause loads spikes. Variability allows a given delay to be extended or reduced by a percentage, specified as a decimal value where 1.0 = 100%.

There are two properties that control variability of the effective delay:

  • minVariance : This is the lower bound on the variance and must be less than or equal to maxVariance. This defaults to 1.0 and can be adjusted to the desired lower limit. For example, to allow the effective timer to be up to 25% shorter than the specified delay, the value can be set to 0.75 (75% of specified delay).
  • maxVariance : This is the upper bound on the variance and must be greater than or equal to minVariance. This defaults to 1.0 and can be adjusted to the desired upper limit. For example, to allow the effective timer to be up to 25% longer than the specified delay, the value can be set to 1.25 (125% of the specified delay).
Used in combination, this provides both upper and/or lower limits, while still introducing variability into timers. By default, both min and max variances are set to 1.0 so that the specified delay is always the actual delay used by the timer.
Since:
1.0
Version:
2022-10-12
  • Constructor Details

    • AdjustableCallback

      public AdjustableCallback(Runnable callback)
      Creates a non-recurring timer with the specified callback method. The timer does not automatically start. Instead, it waits until the calling code calls the start() method.
      Parameters:
      callback - the method called when the timer fires
    • AdjustableCallback

      public AdjustableCallback(boolean recurring, Runnable callback)
      Creates a timer with the specified callback method and recurring flag. The timer does not automatically start. Instead, it waits until the calling code calls the start() method.
      Parameters:
      recurring - true for a recurring timer, false for a one-shot timer
      callback - the method called when the timer fires
    • AdjustableCallback

      public AdjustableCallback(boolean recurring, int delay, Runnable callback)
      Creates a timer with the specified callback method, delay , and recurring flag. The timer starts immediately.
      Parameters:
      recurring - true for a recurring timer, false for a one-shot timer
      delay - the initial delay for the timer
      callback - the method called when the timer fires
  • Method Details

    • isRecurring

      public boolean isRecurring()
      Indicates if this is a recurring timer or not.
      Returns:
      true if this a recurring timer, false if a one-shot timer
    • setRecurring

      public AdjustableCallback setRecurring(boolean recurring)
      Sets the recurring flag.
      Parameters:
      recurring - true to make this timer recurring, or false to make it a one-shot timer
    • getDelay

      public int getDelay()
      Returns the timer's configured delay.
      Returns:
      the delay time (msec)
    • setDelay

      public AdjustableCallback setDelay(int delay)
      Sets a new delay value for the timer.
      • If the timer is already running, then the amount of time already waited is subtracted from the new delay. The timer is restarted with this new delay.
      • If the timer is not running, then only the delay value is updated; the timer is not started.
      To reset the timer to a new value without factoring in current wait time, use setAbsDelay() .
      Parameters:
      delay - the delay (msec)
    • getMinVariance

      public double getMinVariance()
      Retrieves the minimum delay variance.
      Returns:
      the min delay variance
    • setMinVariance

      public AdjustableCallback setMinVariance(double minVariance)
      Sets the minimum delay variance.
      Parameters:
      minVariance - the min variance, any non-negative number
    • getMaxVariance

      public double getMaxVariance()
      Retrieves the maximum delay variance.
      Returns:
      the max delay variance
    • setMaxVariance

      public AdjustableCallback setMaxVariance(double maxVariance)
      Sets the maximum delay variance.
      Parameters:
      maxVariance - the max variance, any non-negative number
    • setAbsDelay

      public AdjustableCallback setAbsDelay(int delay)
      Sets the delay for the timer, regardless of how much time is left on the current timer.
      • If the timer is currently running, then it is stopped and restarted.
      • If the timer is currently stopped, it remains stopped.
      Parameters:
      delay - the delay (msec)
    • setDayRelative

      public AdjustableCallback setDayRelative(int secFromMidnight)
      Sets the delay for the timer, regardless of how much time is left on the current timer. The delay will be computed using day relative semantics. If the current local time is before the day relative time, the timer will trigger on the day relative time today. If current local time is after the day relative time, the timer will trigger tomorrow at the day relative time.
      • If the timer is currently running, then it is stopped and restarted.
      • If the timer is currently stopped, it remains stopped.

      Day relative time is useful for events that must occur at the next occurrence of a local time. This should be used in conjunction with TimeChangeListener so the timer can be rebuilt if the local time or timezone changes.

      When used in recurring mode, the first callback will be at the next occurrence of the specified day relative time and subsequent callbacks will be on 24 hour intervals.

      Parameters:
      secFromMidnight - day relative time in seconds from midnight
    • start

      public AdjustableCallback start()
      Starts the timer.
      • If the timer is currently stopped, then it is started.
      • If the timer is currently running, then this call has no effect.
      This uses the current delay value for the timer, ignoring any previous wait time.
    • stop

      public AdjustableCallback stop()
      Stops the timer. Calls cancel() and exists for api symmetry.
    • setDate

      public boolean setDate(Date date)
      Set the callback to fire at the specified date. This will set the delay to the specified date and automatically start the timer. If the date is in the past, the timer will not be started. Return true if the timer is started. This will clear the recurring flag on the callback if set.
      Parameters:
      date - the date to perform the callback