Class SimRate

All Implemented Interfaces:
RateLimiter, NBComponent, NBComponentAdvisors, NBComponentEvents, NBComponentMetrics, NBComponentProps, NBComponentServices, NBComponentTimeline, NBProviderSearch, NBTokenWords, NBLabeledElement, AutoCloseable, Thread.UncaughtExceptionHandler

public class SimRate extends NBBaseComponent implements RateLimiter, Thread.UncaughtExceptionHandler

Invariants

  • When filler is defined, the pool is being replenished, and the rate limiter is active.
  • Any changes to filler state or filler actions must be guarded by the filler lock.
  • Summary stats are accumulated when the filler is stopped.
  • State is initialized when the filler is started.

In order to use Semaphore, the canonical implementation which is designed to work best with virtual threads, we have to scale time so that the token bucket will fit within 2^31. To make this work across a range of rates from very slow to very fast, the resolution of time tracking has to be set according to the rate specified.


Explanation:

  • The time divisor in the rate is properly established as per interval. Conventionally, a rate specified as "46Kops" is taken to mean "46Kops/s" or per second.
  • The time which passes on the wall clock is the inverse of this, or in the example above, 1/46000 of a second (21739 nanoseconds ideally).
  • At lower rates, like 0.01 ops/s, a number of seconds must pass with time accumulating into the token pool. For 0.01/s, the number of nanoseconds representing a single op is 100_000_000_000, or more than 46 times the value which is representable in a 32 bit semaphore.
  • By scaling the time unit, 0.01 ops/s can be represented as microseconds without losing significant timing resolution with respect to the rate.
  • This scale factor works well to accommodate burst ratios up to 100%
  • Constructor Details

  • Method Details

    • refill

      public long refill()
    • applyRateSpec

      public void applyRateSpec(SimRateSpec updatingSimRateSpec)
      Description copied from interface: RateLimiter
      Modify the rate of a running rate limiter.
      Specified by:
      applyRateSpec in interface RateLimiter
      Parameters:
      updatingSimRateSpec - The rate and burstRatio specification
    • getWaitTimeDuration

      public Duration getWaitTimeDuration()
      Description copied from interface: RateLimiter
      Return the total number of nanoseconds behind schedule that this rate limiter is, but only since the last time the rate spec has changed. When the rate is changed, this value is check-pointed to an accumulator and also included in any subsequent measurement.
      Specified by:
      getWaitTimeDuration in interface RateLimiter
      Returns:
      nanoseconds behind schedule since the rate limiter was started
    • getWaitTimeSeconds

      public double getWaitTimeSeconds()
      Specified by:
      getWaitTimeSeconds in interface RateLimiter
    • initPools

      public void initPools(SimRateSpec simRateSpec)
    • block

      public long block()
      Description copied from interface: RateLimiter

      Block until it is time for the next operation, according to the nanoseconds per op as set by RateLimiter.applyRateSpec(SimRateSpec)

      Specified by:
      block in interface RateLimiter
      Returns:
      the waittime as nanos behind schedule when this op returns. The returned value is required to be greater than or equal to zero.

      Note that accuracy of the returned value is limited by timing precision and calling overhead of the real time clock. It will not generally be better than microseconds. Also, some rate limiting algorithms are unable to efficiently track per-op waittime at speed due to bulk allocation mechanisms necessary to support higher rates.

    • uncaughtException

      public void uncaughtException(Thread t, Throwable e)
      Specified by:
      uncaughtException in interface Thread.UncaughtExceptionHandler
    • getSpec

      public SimRateSpec getSpec()
      Description copied from interface: RateLimiter
      Get the rate spec that this rate limiter was created from.
      Specified by:
      getSpec in interface RateLimiter
      Returns:
      a RateSpec that describes this rate limiter
    • toString

      public String toString()
      Overrides:
      toString in class NBBaseComponent
    • wrap

      public <U, V> Function<U,V> wrap(Function<U,V> f)
    • getTotalWaitTimeDuration

      public Duration getTotalWaitTimeDuration()
      Description copied from interface: RateLimiter
      Return the total number of nanoseconds behind schedule that this rate limiter is, including the full history across all rates. When the rate is changed, this value is check-pointed to an accumulator and also included in any subsequent measurement.
      Specified by:
      getTotalWaitTimeDuration in interface RateLimiter
      Returns:
      nanoseconds behind schedule since the rate limiter was started
    • getStartTime

      public long getStartTime()
      Description copied from interface: RateLimiter
      Return the system nanoseconds at the time when the last rate change was made active by a starting or restarting rate spec.
      Specified by:
      getStartTime in interface RateLimiter
      Returns:
      long nanoseconds