From fd5c41d72083e09818e9f5b8ae53fbdd3428174e Mon Sep 17 00:00:00 2001 From: Craig Bryant Date: Wed, 26 Aug 2015 16:50:14 -0600 Subject: [PATCH] Threshold Engine is rejecting valid measurements In the default case of a period being 60 and the evalation period being 60, the window was being alternately slid 0 slots and then 2 slots. This caused it to reject some recent measurements. To illustrate what was happening, assume a SlidingWindow with a period of 60, and a viewEndTimestamp of 60, and the AlarmDelay default of 30 seconds. AlarmDelay is used to increase the likliehood a metric arrives before the window is evaluated. Also assume the evaluation period is happening at 20 seconds after every minute. On the first one, at time 20, the time is not past the viewEndTimeStamp so nothing happens. On the second one, at time 80, the time is past the viewEndTimeStamp but the window doesn't slide because the time has be > viewEndTimestamp + alarmDelay. At time 140, time is > viewEndTimestamp + alarmDelay so the window is slid. However, since the alarmDelay wasn't being accounted for in the number of slots to slide, it was sliding it one too far. On the next period it wouldn't slide at all and then the next one it would do two again. This was fixed by accounting for alarmDelay when calculating the number of slots to slide Change-Id: I4fcfd41f2de515684b3d0054f9c46c925ee4807b --- .../common/util/stats/SlidingWindowStats.java | 2 +- .../util/stats/SlidingWindowStatsTest.java | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/java/monasca-common-util/src/main/java/monasca/common/util/stats/SlidingWindowStats.java b/java/monasca-common-util/src/main/java/monasca/common/util/stats/SlidingWindowStats.java index f76191ba..afde2bd9 100644 --- a/java/monasca-common-util/src/main/java/monasca/common/util/stats/SlidingWindowStats.java +++ b/java/monasca-common-util/src/main/java/monasca/common/util/stats/SlidingWindowStats.java @@ -216,7 +216,7 @@ public class SlidingWindowStats { } long timeDiff = timestamp - slotEndTimestamp; int slotsToAdvance = (int) (timeDiff / slotWidth); - slotsToAdvance += timeDiff % slotWidth == 0 ? 0 : 1; + slotsToAdvance += (timeDiff % slotWidth) > minDelay ? 1 : 0; for (int i = 0; i < slotsToAdvance; i++) { windowBeginIndex = indexAfter(windowBeginIndex); diff --git a/java/monasca-common-util/src/test/java/monasca/common/util/stats/SlidingWindowStatsTest.java b/java/monasca-common-util/src/test/java/monasca/common/util/stats/SlidingWindowStatsTest.java index 1336e2c8..a5cb62be 100644 --- a/java/monasca-common-util/src/test/java/monasca/common/util/stats/SlidingWindowStatsTest.java +++ b/java/monasca-common-util/src/test/java/monasca/common/util/stats/SlidingWindowStatsTest.java @@ -15,6 +15,8 @@ package monasca.common.util.stats; import static monasca.common.testing.Assert.assertArraysEqual; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.assertFalse; import static org.testng.Assert.fail; import org.testng.annotations.Test; @@ -98,6 +100,38 @@ public class SlidingWindowStatsTest { assertArraysEqual(window.getTimestamps(), new long[] { 12, 15, 18 }); } + public void testSlides() { + SlidingWindowStats window = new SlidingWindowStats(Statistics.Average.class, + TimeResolution.ABSOLUTE, 60, 1, 2, 0); + + assertTrue(window.addValue(1.0, 20)); + window.slideViewTo(20, 30); + assertTrue(window.addValue(1.0, 0)); + + window.slideViewTo(100, 30); + assertFalse(window.addValue(1.0, 0)); + assertTrue(window.addValue(1.0, 61)); + + window.slideViewTo(121, 30); + assertTrue(window.addValue(1.0, 61)); + assertTrue(window.addValue(1.0, 121)); + + window.slideViewTo(180, 30); + assertFalse(window.addValue(1.0, 61)); + assertTrue(window.addValue(1.0, 121)); + assertTrue(window.addValue(1.0, 181)); + + window.slideViewTo(241, 30); + assertFalse(window.addValue(1.0, 121)); + assertTrue(window.addValue(1.0, 181)); + assertTrue(window.addValue(1.0, 241)); + + window.slideViewTo(360, 30); + assertFalse(window.addValue(1.0, 241)); + assertTrue(window.addValue(1.0, 300)); + assertTrue(window.addValue(1.0, 361)); + } + public void shouldAddValueAndGetWindowValues() { SlidingWindowStats window = new SlidingWindowStats(Statistics.Average.class, TimeResolution.ABSOLUTE, 3, 3, 2, 9);