Class ThrottleBin


  • public class ThrottleBin
    extends java.lang.Object
    Throttles for a bin. An instance of this class keeps track of the information needed to bandwidth throttle access to a url belonging to a specific bin. In order to calculate the effective "burst" fetches per second and bytes per second, we need to have some idea what the window is. For example, a long hiatus from fetching could cause overuse of the server when fetching resumes, if the window length is too long. One solution to this problem would be to keep a list of the individual fetches as records. Then, we could "expire" a fetch by discarding the old record. However, this is quite memory consumptive for all but the smallest intervals. Another, better, solution is to hook into the start and end of individual fetches. These will, presumably, occur at the fastest possible rate without long pauses spent doing something else. The only complication is that fetches may well overlap, so we need to "reference count" the fetches to know when to reset the counters. For "fetches per second", we can simply make sure we "schedule" the next fetch at an appropriate time, rather than keep records around. The overall rate may therefore be somewhat less than the specified rate, but that's perfectly acceptable. Some notes on the algorithms used to limit server bandwidth impact ================================================================== In a single connection case, the algorithm we'd want to use works like this. On the first chunk of a series, the total length of time and the number of bytes are recorded. Then, prior to each subsequent chunk, a calculation is done which attempts to hit the bandwidth target by the end of the chunk read, using the rate of the first chunk access as a way of estimating how long it will take to fetch those next n bytes. For a multi-connection case, which this is, it's harder to either come up with a good maximum bandwidth estimate, and harder still to "hit the target", because simultaneous fetches will intrude. The strategy is therefore: 1) The first chunk of any series should proceed without interference from other connections to the same server. The goal here is to get a decent quality estimate without any possibility of overwhelming the server. 2) The bandwidth of the first chunk is treated as the "maximum bandwidth per connection". That is, if other connections are going on, we can presume that each connection will use at most the bandwidth that the first fetch took. Thus, by generating end-time estimates based on this number, we are actually being conservative and using less server bandwidth. 3) For chunks that have started but not finished, we keep track of their size and estimated elapsed time in order to schedule when new chunks from other connections can start. NOTE WELL: This is entirely local in operation
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      protected static class  ThrottleBin.SumClass  
    • Field Summary

      Fields 
      Modifier and Type Field Description
      protected java.lang.String binName
      This is the bin name which this throttle belongs to.
      protected boolean estimateInProgress
      Flag indicating whether rate estimation is in progress yet
      protected boolean estimateValid
      Flag indicating whether a rate estimate is needed
      protected boolean isAlive
      This signals whether the bin is alive or not.
      protected double localMinimum
      The local minimum milliseconds per byte
      protected double minimumMillisecondsPerByte
      The minimum milliseconds per byte
      protected double rateEstimate
      The inverse rate estimate of the first fetch, in ms/byte
      protected int refCount
      This is the reference count for this bin (which records active references)
      protected long seriesStartTime
      The start time of this series
      protected java.lang.String serviceName
      The (anonymous) service name
      protected java.lang.String serviceTypeName
      Service type name
      protected static java.lang.String serviceTypePrefix
      The service type prefix for throttle bins
      protected java.lang.String targetCalcLockName
      The target calculation lock name
      protected static java.lang.String targetCalcLockPrefix
      The target calculation lock prefix
      protected long totalBytesRead
      Total actual bytes read in this series; this includes fetches in progress
    • Constructor Summary

      Constructors 
      Constructor Description
      ThrottleBin​(IThreadContext threadContext, java.lang.String throttlingGroupName, java.lang.String binName)
      Constructor.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void abortFetch()
      Abort the fetch.
      void abortRead()
      Abort a read in progress.
      void beginFetch()
      Note the start of a fetch operation for a bin.
      boolean beginRead​(int byteCount, IBreakCheck breakCheck)
      Note the start of an individual byte read of a specified size.
      protected static java.lang.String buildServiceTypeName​(java.lang.String throttlingGroupName, java.lang.String binName)  
      protected static java.lang.String buildTargetCalcLockName​(java.lang.String throttlingGroupName, java.lang.String binName)  
      boolean endFetch()
      Note the end of a fetch operation.
      void endRead​(int originalCount, int actualCount)
      Note the end of an individual read from the server.
      java.lang.String getBinName()
      Get the bin name.
      protected static byte[] pack​(double targetDouble)  
      void poll​(IThreadContext threadContext)
      Poll this bin
      void shutDown​(IThreadContext threadContext)
      Shut down this bin.
      protected static double unpackTarget​(byte[] data)  
      void updateMinimumMillisecondsPerByte​(double min)
      Update minimumMillisecondsPerBytePerServer
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • isAlive

        protected boolean isAlive
        This signals whether the bin is alive or not.
      • binName

        protected final java.lang.String binName
        This is the bin name which this throttle belongs to.
      • serviceTypeName

        protected final java.lang.String serviceTypeName
        Service type name
      • serviceName

        protected final java.lang.String serviceName
        The (anonymous) service name
      • targetCalcLockName

        protected final java.lang.String targetCalcLockName
        The target calculation lock name
      • minimumMillisecondsPerByte

        protected double minimumMillisecondsPerByte
        The minimum milliseconds per byte
      • localMinimum

        protected double localMinimum
        The local minimum milliseconds per byte
      • refCount

        protected volatile int refCount
        This is the reference count for this bin (which records active references)
      • rateEstimate

        protected double rateEstimate
        The inverse rate estimate of the first fetch, in ms/byte
      • estimateValid

        protected volatile boolean estimateValid
        Flag indicating whether a rate estimate is needed
      • estimateInProgress

        protected volatile boolean estimateInProgress
        Flag indicating whether rate estimation is in progress yet
      • seriesStartTime

        protected long seriesStartTime
        The start time of this series
      • totalBytesRead

        protected long totalBytesRead
        Total actual bytes read in this series; this includes fetches in progress
      • serviceTypePrefix

        protected static final java.lang.String serviceTypePrefix
        The service type prefix for throttle bins
        See Also:
        Constant Field Values
      • targetCalcLockPrefix

        protected static final java.lang.String targetCalcLockPrefix
        The target calculation lock prefix
        See Also:
        Constant Field Values
    • Method Detail

      • buildServiceTypeName

        protected static java.lang.String buildServiceTypeName​(java.lang.String throttlingGroupName,
                                                               java.lang.String binName)
      • buildTargetCalcLockName

        protected static java.lang.String buildTargetCalcLockName​(java.lang.String throttlingGroupName,
                                                                  java.lang.String binName)
      • getBinName

        public java.lang.String getBinName()
        Get the bin name.
      • updateMinimumMillisecondsPerByte

        public void updateMinimumMillisecondsPerByte​(double min)
        Update minimumMillisecondsPerBytePerServer
      • beginFetch

        public void beginFetch()
        Note the start of a fetch operation for a bin. Call this method just before the actual stream access begins. May wait until schedule allows.
      • abortFetch

        public void abortFetch()
        Abort the fetch.
      • beginRead

        public boolean beginRead​(int byteCount,
                                 IBreakCheck breakCheck)
                          throws java.lang.InterruptedException,
                                 BreakException
        Note the start of an individual byte read of a specified size. Call this method just before the read request takes place. Performs the necessary delay prior to reading specified number of bytes from the server.
        Returns:
        false if the wait was interrupted due to the bin being shut down.
        Throws:
        java.lang.InterruptedException
        BreakException
      • abortRead

        public void abortRead()
        Abort a read in progress.
      • endRead

        public void endRead​(int originalCount,
                            int actualCount)
        Note the end of an individual read from the server. Call this just after an individual read completes. Pass the actual number of bytes read to the method.
      • endFetch

        public boolean endFetch()
        Note the end of a fetch operation. Call this method just after the fetch completes.
      • unpackTarget

        protected static double unpackTarget​(byte[] data)
      • pack

        protected static byte[] pack​(double targetDouble)