/* package for testing */ HystrixRollingNumber(Time time, int timeInMilliseconds, int numberOfBuckets) { this.time = time; this.timeInMilliseconds = timeInMilliseconds; this.numberOfBuckets = numberOfBuckets; if (timeInMilliseconds % numberOfBuckets != 0) { throw new IllegalArgumentException("The timeInMilliseconds must divide equally into numberOfBuckets. For example 1000/10 is ok, 1000/11 is not."); } this.bucketSizeInMillseconds = timeInMilliseconds / numberOfBuckets; buckets = new BucketCircularArray(numberOfBuckets); }
Bucket currentBucket = buckets.peekLast(); if (currentBucket != null && currentTime < currentBucket.windowStart + this.bucketSizeInMillseconds) { if (buckets.peekLast() == null) { buckets.addLast(newBucket); return newBucket; } else { Bucket lastBucket = buckets.peekLast(); if (currentTime < lastBucket.windowStart + this.bucketSizeInMillseconds) { } else { // we're past the window so we need to create a new bucket buckets.addLast(new Bucket(lastBucket.windowStart + this.bucketSizeInMillseconds)); return buckets.peekLast(); currentBucket = buckets.peekLast(); if (currentBucket != null) {
/** * Returns an iterator on a copy of the internal array so that the iterator won't fail by buckets being added/removed concurrently. */ public Iterator<Bucket> iterator() { return Collections.unmodifiableList(Arrays.asList(getArray())).iterator(); }
Bucket currentBucket = buckets.peekLast(); if (currentBucket != null && currentTime < currentBucket.windowStart + this.bucketSizeInMillseconds) { if (buckets.peekLast() == null) { buckets.addLast(newBucket); return newBucket; } else { Bucket lastBucket = buckets.peekLast(); if (currentTime < lastBucket.windowStart + this.bucketSizeInMillseconds) { } else { // we're past the window so we need to create a new bucket buckets.addLast(new Bucket(lastBucket.windowStart + this.bucketSizeInMillseconds)); return buckets.peekLast(); currentBucket = buckets.peekLast(); if (currentBucket != null) {
/** * Force a reset of all rolling counters (clear all buckets) so that statistics start being gathered from scratch. * <p> * This does NOT reset the CumulativeSum values. */ public void reset() { // if we are resetting, that means the lastBucket won't have a chance to be captured in CumulativeSum, so let's do it here Bucket lastBucket = buckets.peekLast(); if (lastBucket != null) { cumulativeSum.addBucket(lastBucket); } // clear buckets so we start over again buckets.clear(); }
public Bucket getLast() { return peekLast(); }
/** * Returns an iterator on a copy of the internal array so that the iterator won't fail by buckets being added/removed concurrently. */ public Iterator<Bucket> iterator() { return Collections.unmodifiableList(Arrays.asList(getArray())).iterator(); }
/* package for testing */ HystrixRollingNumber(Time time, int timeInMilliseconds, int numberOfBuckets) { this.time = time; this.timeInMilliseconds = timeInMilliseconds; this.numberOfBuckets = numberOfBuckets; if (timeInMilliseconds % numberOfBuckets != 0) { throw new IllegalArgumentException("The timeInMilliseconds must divide equally into numberOfBuckets. For example 1000/10 is ok, 1000/11 is not."); } this.bucketSizeInMillseconds = timeInMilliseconds / numberOfBuckets; buckets = new BucketCircularArray(numberOfBuckets); }
assertEquals(4, counter.buckets.size()); assertEquals(2, counter.buckets.getLast().getAdder(HystrixRollingNumberEvent.SUCCESS).sum()); assertEquals(3, counter.buckets.getLast().getAdder(HystrixRollingNumberEvent.FAILURE).sum()); assertEquals(1, counter.buckets.getLast().getAdder(HystrixRollingNumberEvent.TIMEOUT).sum()); assertEquals(1, counter.buckets.getLast().getAdder(HystrixRollingNumberEvent.SHORT_CIRCUITED).sum());
assertEquals(1, counter.buckets.size()); assertEquals(30, counter.buckets.getLast().getMaxUpdater(HystrixRollingNumberEvent.THREAD_MAX_ACTIVE).max()); assertEquals(30, counter.getRollingMaxValue(HystrixRollingNumberEvent.THREAD_MAX_ACTIVE)); assertEquals(4, counter.buckets.size()); assertEquals(50, counter.buckets.getLast().getMaxUpdater(HystrixRollingNumberEvent.THREAD_MAX_ACTIVE).max()); assertEquals(50, counter.getValueOfLatestBucket(HystrixRollingNumberEvent.THREAD_MAX_ACTIVE));
@Test public void testShortCircuited() { MockedTime time = new MockedTime(); try { HystrixRollingNumber counter = new HystrixRollingNumber(time, 200, 10); // increment counter.increment(HystrixRollingNumberEvent.SHORT_CIRCUITED); // we should have 1 bucket assertEquals(1, counter.buckets.size()); // the count should be 1 assertEquals(1, counter.buckets.getLast().getAdder(HystrixRollingNumberEvent.SHORT_CIRCUITED).sum()); assertEquals(1, counter.getRollingSum(HystrixRollingNumberEvent.SHORT_CIRCUITED)); // sleep to get to a new bucket time.increment(counter.bucketSizeInMillseconds * 3); // incremenet again in latest bucket counter.increment(HystrixRollingNumberEvent.SHORT_CIRCUITED); // we should have 4 buckets assertEquals(4, counter.buckets.size()); // the counts of the last bucket assertEquals(1, counter.buckets.getLast().getAdder(HystrixRollingNumberEvent.SHORT_CIRCUITED).sum()); // the total counts assertEquals(2, counter.getRollingSum(HystrixRollingNumberEvent.SHORT_CIRCUITED)); } catch (Exception e) { e.printStackTrace(); fail("Exception: " + e.getMessage()); } }
@Test public void testTimeout() { MockedTime time = new MockedTime(); try { HystrixRollingNumber counter = new HystrixRollingNumber(time, 200, 10); // increment counter.increment(HystrixRollingNumberEvent.TIMEOUT); // we should have 1 bucket assertEquals(1, counter.buckets.size()); // the count should be 1 assertEquals(1, counter.buckets.getLast().getAdder(HystrixRollingNumberEvent.TIMEOUT).sum()); assertEquals(1, counter.getRollingSum(HystrixRollingNumberEvent.TIMEOUT)); // sleep to get to a new bucket time.increment(counter.bucketSizeInMillseconds * 3); // incremenet again in latest bucket counter.increment(HystrixRollingNumberEvent.TIMEOUT); // we should have 4 buckets assertEquals(4, counter.buckets.size()); // the counts of the last bucket assertEquals(1, counter.buckets.getLast().getAdder(HystrixRollingNumberEvent.TIMEOUT).sum()); // the total counts assertEquals(2, counter.getRollingSum(HystrixRollingNumberEvent.TIMEOUT)); } catch (Exception e) { e.printStackTrace(); fail("Exception: " + e.getMessage()); } }
private void testCounterType(HystrixRollingNumberEvent type) { MockedTime time = new MockedTime(); try { HystrixRollingNumber counter = new HystrixRollingNumber(time, 200, 10); // increment counter.increment(type); // we should have 1 bucket assertEquals(1, counter.buckets.size()); // the count should be 1 assertEquals(1, counter.buckets.getLast().getAdder(type).sum()); assertEquals(1, counter.getRollingSum(type)); // sleep to get to a new bucket time.increment(counter.bucketSizeInMillseconds * 3); // increment again in latest bucket counter.increment(type); // we should have 4 buckets assertEquals(4, counter.buckets.size()); // the counts of the last bucket assertEquals(1, counter.buckets.getLast().getAdder(type).sum()); // the total counts assertEquals(2, counter.getRollingSum(type)); } catch (Exception e) { e.printStackTrace(); fail("Exception: " + e.getMessage()); } }
assertEquals(1, counter.buckets.size()); assertEquals(10, counter.buckets.getLast().getMaxUpdater(HystrixRollingNumberEvent.THREAD_MAX_ACTIVE).max()); assertEquals(10, counter.getRollingMaxValue(HystrixRollingNumberEvent.THREAD_MAX_ACTIVE)); assertEquals(4, counter.buckets.size()); assertEquals(20, counter.buckets.getLast().getMaxUpdater(HystrixRollingNumberEvent.THREAD_MAX_ACTIVE).max());
@Test public void testCreatesBuckets() { MockedTime time = new MockedTime(); try { HystrixRollingNumber counter = new HystrixRollingNumber(time, 200, 10); // confirm the initial settings assertEquals(200, counter.timeInMilliseconds); assertEquals(10, counter.numberOfBuckets); assertEquals(20, counter.bucketSizeInMillseconds); // we start out with 0 buckets in the queue assertEquals(0, counter.buckets.size()); // add a success in each interval which should result in all 10 buckets being created with 1 success in each for (int i = 0; i < counter.numberOfBuckets; i++) { counter.increment(HystrixRollingNumberEvent.SUCCESS); time.increment(counter.bucketSizeInMillseconds); } // confirm we have all 10 buckets assertEquals(10, counter.buckets.size()); // add 1 more and we should still only have 10 buckets since that's the max counter.increment(HystrixRollingNumberEvent.SUCCESS); assertEquals(10, counter.buckets.size()); } catch (Exception e) { e.printStackTrace(); fail("Exception: " + e.getMessage()); } }
@Test public void testResetBuckets() { MockedTime time = new MockedTime(); try { HystrixRollingNumber counter = new HystrixRollingNumber(time, 200, 10); // we start out with 0 buckets in the queue assertEquals(0, counter.buckets.size()); // add 1 counter.increment(HystrixRollingNumberEvent.SUCCESS); // confirm we have 1 bucket assertEquals(1, counter.buckets.size()); // confirm we still have 1 bucket assertEquals(1, counter.buckets.size()); // add 1 counter.increment(HystrixRollingNumberEvent.SUCCESS); // we should now have a single bucket with no values in it instead of 2 or more buckets assertEquals(1, counter.buckets.size()); } catch (Exception e) { e.printStackTrace(); fail("Exception: " + e.getMessage()); } }
@Test public void testIncrementInSingleBucket() { MockedTime time = new MockedTime(); try { HystrixRollingNumber counter = new HystrixRollingNumber(time, 200, 10); // increment counter.increment(HystrixRollingNumberEvent.SUCCESS); counter.increment(HystrixRollingNumberEvent.SUCCESS); counter.increment(HystrixRollingNumberEvent.SUCCESS); counter.increment(HystrixRollingNumberEvent.SUCCESS); counter.increment(HystrixRollingNumberEvent.FAILURE); counter.increment(HystrixRollingNumberEvent.FAILURE); counter.increment(HystrixRollingNumberEvent.TIMEOUT); // we should have 1 bucket assertEquals(1, counter.buckets.size()); // the count should be 4 assertEquals(4, counter.buckets.getLast().getAdder(HystrixRollingNumberEvent.SUCCESS).sum()); assertEquals(2, counter.buckets.getLast().getAdder(HystrixRollingNumberEvent.FAILURE).sum()); assertEquals(1, counter.buckets.getLast().getAdder(HystrixRollingNumberEvent.TIMEOUT).sum()); } catch (Exception e) { e.printStackTrace(); fail("Exception: " + e.getMessage()); } }
@Test public void testEmptyBucketsFillIn() { MockedTime time = new MockedTime(); try { HystrixRollingNumber counter = new HystrixRollingNumber(time, 200, 10); // add 1 counter.increment(HystrixRollingNumberEvent.SUCCESS); // we should have 1 bucket assertEquals(1, counter.buckets.size()); // wait past 3 bucket time periods (the 1st bucket then 2 empty ones) time.increment(counter.bucketSizeInMillseconds * 3); // add another counter.increment(HystrixRollingNumberEvent.SUCCESS); // we should have 4 (1 + 2 empty + 1 new one) buckets assertEquals(4, counter.buckets.size()); } catch (Exception e) { e.printStackTrace(); fail("Exception: " + e.getMessage()); } }
public Bucket getLast() { return peekLast(); }