@@ -49,9 +49,10 @@ public class HystrixRollingPercentile {
4949 private static final Time ACTUAL_TIME = new ActualTime ();
5050 private final Time time ;
5151 /* package for testing */ final BucketCircularArray buckets ;
52- private final HystrixProperty <Integer > timeInMilliseconds ;
53- private final HystrixProperty <Integer > numberOfBuckets ;
54- private final HystrixProperty <Integer > bucketDataLength ;
52+ private final int timeInMilliseconds ;
53+ private final int numberOfBuckets ;
54+ private final int bucketDataLength ;
55+ private final int bucketSizeInMilliseconds ;
5556 private final HystrixProperty <Boolean > enabled ;
5657
5758 /*
@@ -62,39 +63,71 @@ public class HystrixRollingPercentile {
6263 /**
6364 *
6465 * @param timeInMilliseconds
65- * {@code HystrixProperty<Integer>} for nummber of milliseconds of data that should be tracked
66+ * {@code HystrixProperty<Integer>} for number of milliseconds of data that should be tracked
67+ * Note that this value is represented as a {@link HystrixProperty}, but can not actually be modified
68+ * at runtime, to avoid data loss
6669 * <p>
6770 * Example: 60000 for 1 minute
6871 * @param numberOfBuckets
6972 * {@code HystrixProperty<Integer>} for number of buckets that the time window should be divided into
73+ * Note that this value is represented as a {@link HystrixProperty}, but can not actually be modified
74+ * at runtime, to avoid data loss
7075 * <p>
7176 * Example: 12 for 5 second buckets in a 1 minute window
7277 * @param bucketDataLength
7378 * {@code HystrixProperty<Integer>} for number of values stored in each bucket
79+ * Note that this value is represented as a {@link HystrixProperty}, but can not actually be modified
80+ * at runtime, to avoid data loss
7481 * <p>
7582 * Example: 1000 to store a max of 1000 values in each 5 second bucket
7683 * @param enabled
7784 * {@code HystrixProperty<Boolean>} whether data should be tracked and percentiles calculated.
7885 * <p>
7986 * If 'false' methods will do nothing.
87+ * @deprecated Please use the constructor with non-configurable properties {@link HystrixRollingPercentile(Time, int, int, int, HystrixProperty<Boolean>}
8088 */
89+ @ Deprecated
8190 public HystrixRollingPercentile (HystrixProperty <Integer > timeInMilliseconds , HystrixProperty <Integer > numberOfBuckets , HystrixProperty <Integer > bucketDataLength , HystrixProperty <Boolean > enabled ) {
91+ this (timeInMilliseconds .get (), numberOfBuckets .get (), bucketDataLength .get (), enabled );
92+ }
93+
94+ /**
95+ *
96+ * @param timeInMilliseconds
97+ * number of milliseconds of data that should be tracked
98+ * <p>
99+ * Example: 60000 for 1 minute
100+ * @param numberOfBuckets
101+ * number of buckets that the time window should be divided into
102+ * <p>
103+ * Example: 12 for 5 second buckets in a 1 minute window
104+ * @param bucketDataLength
105+ * number of values stored in each bucket
106+ * <p>
107+ * Example: 1000 to store a max of 1000 values in each 5 second bucket
108+ * @param enabled
109+ * {@code HystrixProperty<Boolean>} whether data should be tracked and percentiles calculated.
110+ * <p>
111+ * If 'false' methods will do nothing.
112+ */
113+ public HystrixRollingPercentile (int timeInMilliseconds , int numberOfBuckets , int bucketDataLength , HystrixProperty <Boolean > enabled ) {
82114 this (ACTUAL_TIME , timeInMilliseconds , numberOfBuckets , bucketDataLength , enabled );
83115
84116 }
85117
86- /* package for testing */ HystrixRollingPercentile (Time time , HystrixProperty < Integer > timeInMilliseconds , HystrixProperty < Integer > numberOfBuckets , HystrixProperty < Integer > bucketDataLength , HystrixProperty <Boolean > enabled ) {
118+ /* package for testing */ HystrixRollingPercentile (Time time , int timeInMilliseconds , int numberOfBuckets , int bucketDataLength , HystrixProperty <Boolean > enabled ) {
87119 this .time = time ;
88120 this .timeInMilliseconds = timeInMilliseconds ;
89121 this .numberOfBuckets = numberOfBuckets ;
90122 this .bucketDataLength = bucketDataLength ;
91123 this .enabled = enabled ;
92124
93- if (this .timeInMilliseconds . get () % this .numberOfBuckets . get () != 0 ) {
125+ if (this .timeInMilliseconds % this .numberOfBuckets != 0 ) {
94126 throw new IllegalArgumentException ("The timeInMilliseconds must divide equally into numberOfBuckets. For example 1000/10 is ok, 1000/11 is not." );
95127 }
128+ this .bucketSizeInMilliseconds = this .timeInMilliseconds / this .numberOfBuckets ;
96129
97- buckets = new BucketCircularArray (this .numberOfBuckets . get () );
130+ buckets = new BucketCircularArray (this .numberOfBuckets );
98131 }
99132
100133 /**
@@ -166,10 +199,6 @@ private PercentileSnapshot getCurrentPercentileSnapshot() {
166199 return currentPercentileSnapshot ;
167200 }
168201
169- private int getBucketSizeInMilliseconds () {
170- return timeInMilliseconds .get () / numberOfBuckets .get ();
171- }
172-
173202 private ReentrantLock newBucketLock = new ReentrantLock ();
174203
175204 private Bucket getCurrentBucket () {
@@ -183,7 +212,7 @@ private Bucket getCurrentBucket() {
183212 * NOTE: This is thread-safe because it's accessing 'buckets' which is a LinkedBlockingDeque
184213 */
185214 Bucket currentBucket = buckets .peekLast ();
186- if (currentBucket != null && currentTime < currentBucket .windowStart + getBucketSizeInMilliseconds () ) {
215+ if (currentBucket != null && currentTime < currentBucket .windowStart + this . bucketSizeInMilliseconds ) {
187216 // if we're within the bucket 'window of time' return the current one
188217 // NOTE: We do not worry if we are BEFORE the window in a weird case of where thread scheduling causes that to occur,
189218 // we'll just use the latest as long as we're not AFTER the window
@@ -218,29 +247,29 @@ private Bucket getCurrentBucket() {
218247 try {
219248 if (buckets .peekLast () == null ) {
220249 // the list is empty so create the first bucket
221- Bucket newBucket = new Bucket (currentTime , bucketDataLength . get () );
250+ Bucket newBucket = new Bucket (currentTime , bucketDataLength );
222251 buckets .addLast (newBucket );
223252 return newBucket ;
224253 } else {
225254 // We go into a loop so that it will create as many buckets as needed to catch up to the current time
226255 // as we want the buckets complete even if we don't have transactions during a period of time.
227- for (int i = 0 ; i < numberOfBuckets . get () ; i ++) {
256+ for (int i = 0 ; i < numberOfBuckets ; i ++) {
228257 // we have at least 1 bucket so retrieve it
229258 Bucket lastBucket = buckets .peekLast ();
230- if (currentTime < lastBucket .windowStart + getBucketSizeInMilliseconds () ) {
259+ if (currentTime < lastBucket .windowStart + this . bucketSizeInMilliseconds ) {
231260 // if we're within the bucket 'window of time' return the current one
232261 // NOTE: We do not worry if we are BEFORE the window in a weird case of where thread scheduling causes that to occur,
233262 // we'll just use the latest as long as we're not AFTER the window
234263 return lastBucket ;
235- } else if (currentTime - (lastBucket .windowStart + getBucketSizeInMilliseconds ()) > timeInMilliseconds . get () ) {
264+ } else if (currentTime - (lastBucket .windowStart + this . bucketSizeInMilliseconds ) > timeInMilliseconds ) {
236265 // the time passed is greater than the entire rolling counter so we want to clear it all and start from scratch
237266 reset ();
238267 // recursively call getCurrentBucket which will create a new bucket and return it
239268 return getCurrentBucket ();
240269 } else { // we're past the window so we need to create a new bucket
241270 Bucket [] allBuckets = buckets .getArray ();
242271 // create a new bucket and add it as the new 'last' (once this is done other threads will start using it on subsequent retrievals)
243- buckets .addLast (new Bucket (lastBucket .windowStart + getBucketSizeInMilliseconds () , bucketDataLength . get () ));
272+ buckets .addLast (new Bucket (lastBucket .windowStart + this . bucketSizeInMilliseconds , bucketDataLength ));
244273 // we created a new bucket so let's re-generate the PercentileSnapshot (not including the new bucket)
245274 currentPercentileSnapshot = new PercentileSnapshot (allBuckets );
246275 }
0 commit comments