public CriticalComponentImpl(CriticalAnalyzer analyzer, int numberOfPaths) { if (analyzer == null) { analyzer = EmptyCriticalAnalyzer.getInstance(); } this.analyzer = analyzer; if (analyzer.isMeasuring()) { measures = new CriticalMeasure[numberOfPaths]; for (int i = 0; i < numberOfPaths; i++) { measures[i] = new CriticalMeasure(); } } else { measures = null; } }
public CriticalMeasure() { //prefer this approach instead of using some fixed value because System::nanoTime could change sign //with long running processes enterCritical(); leaveCritical(); }
@Override public boolean isExpired(long timeout) { for (int i = 0; i < measures.length; i++) { if (measures[i].isExpired(timeout)) { return true; } } return false; } }
@Test public void testCriticalFailure() throws Exception { CriticalAnalyzer analyzer = new CriticalAnalyzerImpl(); CriticalComponent component = new CriticalComponentImpl(analyzer, 5); CriticalMeasure measure = new CriticalMeasure(component, 1); long time = System.nanoTime(); measure.enterCritical(); CriticalMeasure.TIME_ENTER_UPDATER.set(measure, time - TimeUnit.MINUTES.toNanos(5)); CriticalMeasure.TIME_LEFT_UPDATER.set(measure, time - TimeUnit.MINUTES.toNanos(10)); Assert.assertTrue(measure.isExpired(TimeUnit.SECONDS.toNanos(30))); measure.leaveCritical(); } }
@Test public void testCriticalMeasureTakingLongButSucceeding() throws Exception { CriticalAnalyzer analyzer = new CriticalAnalyzerImpl(); CriticalComponent component = new CriticalComponentImpl(analyzer, 5); CriticalMeasure measure = new CriticalMeasure(component, 1); long time = System.nanoTime(); CriticalMeasure.TIME_ENTER_UPDATER.set(measure, time - TimeUnit.MINUTES.toNanos(5)); measure.leaveCritical(); Assert.assertFalse(measure.isExpired(TimeUnit.SECONDS.toNanos(30))); }
public void leaveCritical() { if (logger.isTraceEnabled()) { CriticalAnalyzer analyzer = component != null ? component.getCriticalAnalyzer() : null; if (analyzer != null) { long nanoTimeout = analyzer.getTimeoutNanoSeconds(); if (isExpired(nanoTimeout)) { logger.trace("Path " + id + " on component " + getComponentName() + " is taking too long, leaving at", new Exception("entered")); logger.trace("Path " + id + " on component " + getComponentName() + " is taking too long, entered at", traceEnter); } } traceEnter = null; } TIME_LEFT_UPDATER.lazySet(this, System.nanoTime()); }
@Test public void testCriticalMeasure() throws Exception { CriticalMeasure measure = new CriticalMeasure(null, 1); long time = System.nanoTime(); CriticalMeasure.TIME_ENTER_UPDATER.set(measure, time - TimeUnit.MINUTES.toNanos(5)); CriticalMeasure.TIME_LEFT_UPDATER.set(measure, time); Assert.assertFalse(measure.isExpired(TimeUnit.SECONDS.toNanos(30))); }
@Override public void enterCritical(int path) { if (analyzer.isMeasuring()) { measures[path].enterCritical(); } }
@Override public void leaveCritical(int path) { if (analyzer.isMeasuring()) { measures[path].leaveCritical(); } }
public boolean isExpired(long timeout) { final long timeLeft = TIME_LEFT_UPDATER.get(this); final long timeEnter = TIME_ENTER_UPDATER.get(this); //due to how System::nanoTime works is better to use differences to prevent numerical overflow while comparing if (timeLeft - timeEnter < 0) { boolean expired = System.nanoTime() - timeEnter > timeout; if (expired) { Exception thistraceEnter = this.traceEnter; if (thistraceEnter != null) { logger.warn("Component " + getComponentName() + " is expired on path " + id, thistraceEnter); } else { logger.warn("Component " + getComponentName() + " is expired on path " + id); } } return expired; } return false; }
public void leaveCritical() { if (logger.isTraceEnabled()) { CriticalAnalyzer analyzer = component != null ? component.getCriticalAnalyzer() : null; if (analyzer != null) { long nanoTimeout = analyzer.getTimeoutNanoSeconds(); if (isExpired(nanoTimeout)) { logger.trace("Path " + id + " on component " + getComponentName() + " is taking too long, leaving at", new Exception("entered")); logger.trace("Path " + id + " on component " + getComponentName() + " is taking too long, entered at", traceEnter); } } traceEnter = null; } TIME_LEFT_UPDATER.lazySet(this, System.nanoTime()); }
@Override public void enterCritical(int path) { if (analyzer.isMeasuring()) { measures[path].enterCritical(); } }
@Override public void leaveCritical(int path) { if (analyzer.isMeasuring()) { measures[path].leaveCritical(); } }
public boolean isExpired(long timeout) { final long timeLeft = TIME_LEFT_UPDATER.get(this); final long timeEnter = TIME_ENTER_UPDATER.get(this); //due to how System::nanoTime works is better to use differences to prevent numerical overflow while comparing if (timeLeft - timeEnter < 0) { boolean expired = System.nanoTime() - timeEnter > timeout; if (expired) { Exception thistraceEnter = this.traceEnter; if (thistraceEnter != null) { logger.warn("Component " + getComponentName() + " is expired on path " + id, thistraceEnter); } else { logger.warn("Component " + getComponentName() + " is expired on path " + id); } } return expired; } return false; }
public void leaveCritical() { if (logger.isTraceEnabled()) { CriticalAnalyzer analyzer = component != null ? component.getCriticalAnalyzer() : null; if (analyzer != null) { long nanoTimeout = analyzer.getTimeoutNanoSeconds(); if (isExpired(nanoTimeout)) { logger.trace("Path " + id + " on component " + getComponentName() + " is taking too long, leaving at", new Exception("entered")); logger.trace("Path " + id + " on component " + getComponentName() + " is taking too long, entered at", traceEnter); } } traceEnter = null; } TIME_LEFT_UPDATER.lazySet(this, System.nanoTime()); }
public CriticalMeasure() { //prefer this approach instead of using some fixed value because System::nanoTime could change sign //with long running processes enterCritical(); leaveCritical(); }
@Override public void enterCritical(int path) { if (analyzer.isMeasuring()) { measures[path].enterCritical(); } }
@Override public void leaveCritical(int path) { if (analyzer.isMeasuring()) { measures[path].leaveCritical(); } }
@Override public boolean isExpired(long timeout) { for (int i = 0; i < measures.length; i++) { if (measures[i].isExpired(timeout)) { return true; } } return false; } }
public CriticalComponentImpl(CriticalAnalyzer analyzer, int numberOfPaths) { if (analyzer == null) { analyzer = EmptyCriticalAnalyzer.getInstance(); } this.analyzer = analyzer; if (analyzer.isMeasuring()) { measures = new CriticalMeasure[numberOfPaths]; for (int i = 0; i < numberOfPaths; i++) { measures[i] = new CriticalMeasure(this, i); } } else { measures = null; } }