This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.discovery.commons-1.0.10 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-discovery-commons.git
commit dbdcc687bd7a67ed53aa6628df6c751340cf3b23 Author: Stefan Egli <[email protected]> AuthorDate: Wed Nov 18 12:12:21 2015 +0000 SLING-5310: adding cancelDelaying to MinEventDelayHandler - plus added a testReactivate test method which checks the scenario described in this ticket. Plus also added somewhat more logging to the HeartbeatHandler to help debugging should something similar reoccur git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/discovery/commons@1714984 13f79535-47bb-0310-9956-ffa450edef68 --- .../providers/base/MinEventDelayHandler.java | 14 ++++ .../providers/base/ViewStateManagerImpl.java | 4 ++ .../providers/base/TestMinEventDelayHandler.java | 77 +++++++++++++++++++++- 3 files changed, 93 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/sling/discovery/commons/providers/base/MinEventDelayHandler.java b/src/main/java/org/apache/sling/discovery/commons/providers/base/MinEventDelayHandler.java index a8a0066..167a0ba 100644 --- a/src/main/java/org/apache/sling/discovery/commons/providers/base/MinEventDelayHandler.java +++ b/src/main/java/org/apache/sling/discovery/commons/providers/base/MinEventDelayHandler.java @@ -49,6 +49,8 @@ class MinEventDelayHandler { private Lock lock; + private volatile int cancelCnt = 0; + MinEventDelayHandler(ViewStateManagerImpl viewStateManager, Lock lock, DiscoveryService discoveryService, Scheduler scheduler, long minEventDelaySecs) { @@ -117,11 +119,17 @@ class MinEventDelayHandler { } private boolean triggerAsyncDelaying(BaseTopologyView newView) { + final int validCancelCnt = cancelCnt; final boolean triggered = runAfter(minEventDelaySecs /*seconds*/ , new Runnable() { public void run() { lock.lock(); try{ + if (cancelCnt!=validCancelCnt) { + logger.info("asyncDelay.run: got cancelled (validCancelCnt="+validCancelCnt+", cancelCnt="+cancelCnt+"), quitting."); + return; + } + // unlock the CHANGED event for any subsequent call to handleTopologyChanged() isDelaying = false; @@ -192,4 +200,10 @@ class MinEventDelayHandler { return isDelaying; } + public void cancelDelaying() { + logger.info("cancelDelaying: flagging cancelCnt as invalid: "+cancelCnt); + cancelCnt++; + isDelaying = false; + } + } diff --git a/src/main/java/org/apache/sling/discovery/commons/providers/base/ViewStateManagerImpl.java b/src/main/java/org/apache/sling/discovery/commons/providers/base/ViewStateManagerImpl.java index 53cfbff..b6bff61 100644 --- a/src/main/java/org/apache/sling/discovery/commons/providers/base/ViewStateManagerImpl.java +++ b/src/main/java/org/apache/sling/discovery/commons/providers/base/ViewStateManagerImpl.java @@ -336,6 +336,10 @@ public class ViewStateManagerImpl implements ViewStateManager { if (consistencyService!=null) { consistencyService.cancelSync(); } + + if (minEventDelayHandler!=null) { + minEventDelayHandler.cancelDelaying(); + } logger.trace("handleDeactivated: setting isChanging to false"); isChanging = false; diff --git a/src/test/java/org/apache/sling/discovery/commons/providers/base/TestMinEventDelayHandler.java b/src/test/java/org/apache/sling/discovery/commons/providers/base/TestMinEventDelayHandler.java index fc78c44..002fc7e 100644 --- a/src/test/java/org/apache/sling/discovery/commons/providers/base/TestMinEventDelayHandler.java +++ b/src/test/java/org/apache/sling/discovery/commons/providers/base/TestMinEventDelayHandler.java @@ -20,7 +20,9 @@ package org.apache.sling.discovery.commons.providers.base; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import java.lang.reflect.Field; import java.util.Random; import java.util.UUID; import java.util.concurrent.locks.ReentrantLock; @@ -86,11 +88,82 @@ public class TestMinEventDelayHandler { discoveryLogger.setLevel(logLevel); } + + @Test + public void testReactivate() throws Exception { + logger.info("testReactivate: start"); + // install a minEventDelayHandler with a longer delay of 2sec + mgr.installMinEventDelayHandler(sds, scheduler, 2); + + final DummyListener listener = new DummyListener(); + logger.info("testReactivate: calling handleActivated"); + mgr.bind(listener); + mgr.handleActivated(); + TestHelper.assertNoEvents(listener); + final DummyTopologyView view1 = new DummyTopologyView().addInstance(); + final DummyTopologyView view2 = DummyTopologyView.clone(view1).addInstance(UUID.randomUUID().toString(), + (DefaultClusterView) view1.getLocalInstance().getClusterView(), false, false); + final DummyTopologyView view3 = DummyTopologyView.clone(view1).addInstance(UUID.randomUUID().toString(), + (DefaultClusterView) view1.getLocalInstance().getClusterView(), false, false); + logger.info("testReactivate: calling handleNewView..."); + mgr.handleNewView(view1); + logger.info("testReactivate: asserting init event"); + TestHelper.assertEvents(mgr, listener, EventHelper.newInitEvent(view1)); + logger.info("testReactivate: calling handleChanging..."); + mgr.handleChanging(); + TestHelper.assertEvents(mgr, listener, EventHelper.newChangingEvent(view1)); + logger.info("testReactivate: calling handleNewView 2nd time..."); + mgr.handleNewView(view2); + TestHelper.assertNoEvents(listener); + // make sure the MinEventDelayHandler finds a topology when coming back from the delaying, so: + sds.setTopoology(view2); + logger.info("testReactivate: waiting for async events to have been processed - max 4sec"); + assertEquals(0, mgr.waitForAsyncEvents(4000)); + logger.info("testReactivate: asserting CHANGED event"); + TestHelper.assertEvents(mgr, listener, EventHelper.newChangedEvent(view1, view2)); + + // now do the above again, but this time do a handleDeactivated before receiving another changed event + logger.info("testReactivate: calling handleChanging..."); + mgr.handleChanging(); + TestHelper.assertEvents(mgr, listener, EventHelper.newChangingEvent(view2)); + logger.info("testReactivate: calling handleNewView 2nd time..."); + mgr.handleNewView(view3); + TestHelper.assertNoEvents(listener); + // make sure the MinEventDelayHandler finds a topology when coming back from the delaying, so: + sds.setTopoology(view3); + + logger.info("testReactivate: doing handleDeactivated"); + final AsyncEventSender asyncEventSender = mgr.getAsyncEventSender(); + Field field = mgr.getClass().getDeclaredField("minEventDelayHandler"); + field.setAccessible(true); + MinEventDelayHandler minEventDelayHandler = (MinEventDelayHandler) field.get(mgr); + assertNotNull(minEventDelayHandler); + + // marking view3 as not current + view3.setNotCurrent(); + sds.setTopoology(view3); + + mgr.handleDeactivated(); + TestHelper.assertNoEvents(listener); + + logger.info("testReactivate: now waiting 5 sec to make sure the MinEventDelayHandler would be finished"); + TestHelper.assertNoEvents(listener); + Thread.sleep(5000); + logger.info("testReactivate: after those 5 sec there should however still not be any new event"); + TestHelper.assertNoEvents(listener); + + int cnt = asyncEventSender.getInFlightEventCnt(); + if (minEventDelayHandler!=null && minEventDelayHandler.isDelaying()) { + cnt++; + } + assertEquals(0, cnt); + } + private void assertNoEvents(DummyListener listener) { assertEquals(0, listener.countEvents()); } - @Test @Ignore + @Test public void testNormalDelaying() throws Exception { final DummyListener listener = new DummyListener(); // first activate @@ -115,7 +188,7 @@ public class TestMinEventDelayHandler { } } - @Test @Ignore + @Test public void testFailedDelaying() throws Exception { scheduler.failMode(); final DummyListener listener = new DummyListener(); -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
