Search in sources :

Example 1 with DiscoveryServiceImpl

use of org.apache.sling.discovery.impl.DiscoveryServiceImpl in project sling by apache.

the class HeartbeatTest method doTestPartitioning.

public void doTestPartitioning(boolean scheduler) throws Throwable {
    logger.info("doTestPartitioning: creating slowMachine...");
    FullJR2VirtualInstanceBuilder builder = newBuilder();
    builder.setDebugName("slow").newRepository("/var/discovery/impl/", true).setConnectorPingTimeout(10).setConnectorPingInterval(999).setMinEventDelay(0).withFailingScheduler(!scheduler);
    FullJR2VirtualInstance slowMachine = builder.fullBuild();
    assertEquals(1, slowMachine.getDiscoveryService().getTopology().getInstances().size());
    assertEquals(slowMachine.getSlingId(), slowMachine.getDiscoveryService().getTopology().getInstances().iterator().next().getSlingId());
    instances.add(slowMachine);
    // wait 10ms to ensure 'slowMachine' has the lowerst leaderElectionId (to become leader)
    Thread.sleep(10);
    SimpleTopologyEventListener slowListener = new SimpleTopologyEventListener("slow");
    slowMachine.bindTopologyEventListener(slowListener);
    logger.info("doTestPartitioning: creating fastMachine1...");
    FullJR2VirtualInstanceBuilder fastBuilder1 = newBuilder();
    fastBuilder1.setDebugName("fast1").useRepositoryOf(slowMachine).setConnectorPingTimeout(10).setConnectorPingInterval(1).setMinEventDelay(0).withFailingScheduler(!scheduler);
    FullJR2VirtualInstance fastMachine1 = fastBuilder1.fullBuild();
    assertEquals(1, fastMachine1.getDiscoveryService().getTopology().getInstances().size());
    assertEquals(fastMachine1.getSlingId(), fastMachine1.getDiscoveryService().getTopology().getInstances().iterator().next().getSlingId());
    instances.add(fastMachine1);
    // wait 10ms to ensure 'fastMachine1' has the 2nd lowerst leaderElectionId (to become leader during partitioning)
    Thread.sleep(10);
    SimpleTopologyEventListener fastListener1 = new SimpleTopologyEventListener("fast1");
    fastMachine1.bindTopologyEventListener(fastListener1);
    logger.info("doTestPartitioning: creating fastMachine2...");
    FullJR2VirtualInstanceBuilder fullBuilder2 = newBuilder();
    fullBuilder2.setDebugName("fast2").useRepositoryOf(slowMachine).setConnectorPingTimeout(10).setConnectorPingInterval(1).setMinEventDelay(0).withFailingScheduler(!scheduler);
    FullJR2VirtualInstance fastMachine2 = fullBuilder2.fullBuild();
    assertEquals(1, fastMachine2.getDiscoveryService().getTopology().getInstances().size());
    assertEquals(fastMachine2.getSlingId(), fastMachine2.getDiscoveryService().getTopology().getInstances().iterator().next().getSlingId());
    instances.add(fastMachine2);
    SimpleTopologyEventListener fastListener2 = new SimpleTopologyEventListener("fast2");
    fastMachine2.bindTopologyEventListener(fastListener2);
    logger.info("doTestPartitioning: creating fastMachine3...");
    FullJR2VirtualInstanceBuilder fullBuilder3 = newBuilder();
    fullBuilder3.setDebugName("fast3").useRepositoryOf(slowMachine).setConnectorPingTimeout(10).setConnectorPingInterval(1).setMinEventDelay(0).withFailingScheduler(!scheduler);
    FullJR2VirtualInstance fastMachine3 = fullBuilder3.fullBuild();
    assertEquals(1, fastMachine3.getDiscoveryService().getTopology().getInstances().size());
    assertEquals(fastMachine3.getSlingId(), fastMachine3.getDiscoveryService().getTopology().getInstances().iterator().next().getSlingId());
    instances.add(fastMachine3);
    SimpleTopologyEventListener fastListener3 = new SimpleTopologyEventListener("fast3");
    fastMachine3.bindTopologyEventListener(fastListener3);
    logger.info("doTestPartitioning: creating fastMachine4...");
    FullJR2VirtualInstanceBuilder fullBuilder4 = newBuilder();
    fullBuilder4.setDebugName("fast4").useRepositoryOf(slowMachine).setConnectorPingTimeout(10).setConnectorPingInterval(1).setMinEventDelay(0).withFailingScheduler(!scheduler);
    FullJR2VirtualInstance fastMachine4 = fullBuilder4.fullBuild();
    assertEquals(1, fastMachine4.getDiscoveryService().getTopology().getInstances().size());
    assertEquals(fastMachine4.getSlingId(), fastMachine4.getDiscoveryService().getTopology().getInstances().iterator().next().getSlingId());
    instances.add(fastMachine4);
    SimpleTopologyEventListener fastListener4 = new SimpleTopologyEventListener("fast4");
    fastMachine4.bindTopologyEventListener(fastListener4);
    logger.info("doTestPartitioning: --------------------------------");
    logger.info("doTestPartitioning: letting heartbeats be sent by all instances for a few loops...");
    logger.info("doTestPartitioning: --------------------------------");
    HeartbeatHandler hhSlow = slowMachine.getHeartbeatHandler();
    for (int i = 0; i < 5; i++) {
        logger.info("doTestPartitioning: --------------------------------");
        logger.info("doTestPartitioning: doing pinging with hhSlow now...");
        logger.info("doTestPartitioning: --------------------------------");
        synchronized (lock(hhSlow)) {
            hhSlow.issueHeartbeat();
            hhSlow.doCheckView();
        }
        if (!scheduler) {
            logger.info("doTestPartitioning: --------------------------------");
            logger.info("doTestPartitioning: doing pinging with fastMachine1 now...");
            logger.info("doTestPartitioning: --------------------------------");
            synchronized (lock(fastMachine1.getHeartbeatHandler())) {
                fastMachine1.getHeartbeatHandler().issueHeartbeat();
                fastMachine1.getHeartbeatHandler().doCheckView();
            }
            logger.info("doTestPartitioning: --------------------------------");
            logger.info("doTestPartitioning: doing pinging with fastMachine2 now...");
            logger.info("doTestPartitioning: --------------------------------");
            synchronized (lock(fastMachine2.getHeartbeatHandler())) {
                fastMachine2.getHeartbeatHandler().issueHeartbeat();
                fastMachine2.getHeartbeatHandler().doCheckView();
            }
            logger.info("doTestPartitioning: --------------------------------");
            logger.info("doTestPartitioning: doing pinging with fastMachine3 now...");
            logger.info("doTestPartitioning: --------------------------------");
            synchronized (lock(fastMachine3.getHeartbeatHandler())) {
                fastMachine3.getHeartbeatHandler().issueHeartbeat();
                fastMachine3.getHeartbeatHandler().doCheckView();
            }
            logger.info("doTestPartitioning: --------------------------------");
            logger.info("doTestPartitioning: doing pinging with fastMachine4 now...");
            logger.info("doTestPartitioning: --------------------------------");
            synchronized (lock(fastMachine4.getHeartbeatHandler())) {
                fastMachine4.getHeartbeatHandler().issueHeartbeat();
                fastMachine4.getHeartbeatHandler().doCheckView();
            }
        }
        Thread.sleep(1000);
    }
    // at this stage the 4 fast plus the slow instance should all see each other
    logger.info("doTestPartitioning: all 4 instances should have agreed on seeing each other");
    assertNotNull(fastListener1.getLastEvent());
    assertEquals(TopologyEvent.Type.TOPOLOGY_INIT, fastListener1.getLastEvent().getType());
    assertEquals(5, fastListener1.getLastEvent().getNewView().getInstances().size());
    assertFalse(fastListener1.getLastEvent().getNewView().getLocalInstance().isLeader());
    assertNotNull(fastListener2.getLastEvent());
    assertEquals(TopologyEvent.Type.TOPOLOGY_INIT, fastListener2.getLastEvent().getType());
    assertEquals(5, fastListener2.getLastEvent().getNewView().getInstances().size());
    assertFalse(fastListener2.getLastEvent().getNewView().getLocalInstance().isLeader());
    assertNotNull(fastListener3.getLastEvent());
    assertEquals(TopologyEvent.Type.TOPOLOGY_INIT, fastListener3.getLastEvent().getType());
    assertEquals(5, fastListener3.getLastEvent().getNewView().getInstances().size());
    assertFalse(fastListener3.getLastEvent().getNewView().getLocalInstance().isLeader());
    assertNotNull(fastListener4.getLastEvent());
    assertEquals(TopologyEvent.Type.TOPOLOGY_INIT, fastListener4.getLastEvent().getType());
    assertEquals(5, fastListener4.getLastEvent().getNewView().getInstances().size());
    assertFalse(fastListener4.getLastEvent().getNewView().getLocalInstance().isLeader());
    assertNotNull(slowListener.getLastEvent());
    assertEquals(TopologyEvent.Type.TOPOLOGY_INIT, slowListener.getLastEvent().getType());
    assertEquals(5, slowListener.getLastEvent().getNewView().getInstances().size());
    assertTrue(slowListener.getLastEvent().getNewView().getLocalInstance().isLeader());
    // after 12sec the slow instance' heartbeat should have timed out
    logger.info("doTestPartitioning: letting slowMachine NOT send any heartbeats for 12sec, only the fast ones do...");
    for (int i = 0; i < 12; i++) {
        if (!scheduler) {
            synchronized (lock(fastMachine1.getHeartbeatHandler())) {
                fastMachine1.getHeartbeatHandler().issueHeartbeat();
                fastMachine1.getHeartbeatHandler().doCheckView();
            }
            synchronized (lock(fastMachine2.getHeartbeatHandler())) {
                fastMachine2.getHeartbeatHandler().issueHeartbeat();
                fastMachine2.getHeartbeatHandler().doCheckView();
            }
            synchronized (lock(fastMachine3.getHeartbeatHandler())) {
                fastMachine3.getHeartbeatHandler().issueHeartbeat();
                fastMachine3.getHeartbeatHandler().doCheckView();
            }
            synchronized (lock(fastMachine4.getHeartbeatHandler())) {
                fastMachine4.getHeartbeatHandler().issueHeartbeat();
                fastMachine4.getHeartbeatHandler().doCheckView();
            }
        }
        Thread.sleep(1000);
    }
    logger.info("doTestPartitioning: this should now have decoupled slowMachine from the other 4...");
    // so the fast listeners should only see 4 instances remaining
    for (int i = 0; i < 7; i++) {
        logger.info("doTestPartitioning: sleeping 2sec...");
        Thread.sleep(2000);
        logger.info("doTestPartitioning: the 4 fast machines should all just see themselves...");
        assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, fastListener1.getLastEvent().getType());
        assertEquals(4, fastListener1.getLastEvent().getNewView().getInstances().size());
        assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, fastListener2.getLastEvent().getType());
        assertEquals(4, fastListener2.getLastEvent().getNewView().getInstances().size());
        assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, fastListener3.getLastEvent().getType());
        assertEquals(4, fastListener3.getLastEvent().getNewView().getInstances().size());
        assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, fastListener4.getLastEvent().getType());
        assertEquals(4, fastListener4.getLastEvent().getNewView().getInstances().size());
        assertTrue(fastListener1.getLastEvent().getNewView().getLocalInstance().isLeader());
        assertFalse(fastListener2.getLastEvent().getNewView().getLocalInstance().isLeader());
        assertFalse(fastListener3.getLastEvent().getNewView().getLocalInstance().isLeader());
        assertFalse(fastListener4.getLastEvent().getNewView().getLocalInstance().isLeader());
        // and the slow instance should be isolated
        assertFalse(slowMachine.getDiscoveryService().getTopology().isCurrent());
        // assertEquals(5, slowMachine.getDiscoveryService().getTopology().getInstances().size());
        if (i == 0) {
            assertEquals(TopologyEvent.Type.TOPOLOGY_INIT, slowListener.getLastEvent().getType());
        } else {
            assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGING, slowListener.getLastEvent().getType());
        }
        //TODO but only after 'handlePotentialTopologyChange' is called
        // which either happens via handleTopologyChanged (via the TopologyChangeHandler)
        // or via updateProperties
        DiscoveryServiceImpl slowDisco = (DiscoveryServiceImpl) slowMachine.getDiscoveryService();
        slowDisco.updateProperties();
        // that should have triggered an async event - which takes a little moment
        Thread.sleep(500);
        assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGING, slowListener.getLastEvent().getType());
        assertEquals(2, slowListener.getEventCount());
        TopologyView slowTopo = slowMachine.getDiscoveryService().getTopology();
        assertNotNull(slowTopo);
        assertFalse(slowTopo.isCurrent());
        //assertEquals(5, slowTopo.getInstances().size());
        if (!scheduler) {
            synchronized (lock(fastMachine1.getHeartbeatHandler())) {
                fastMachine1.getHeartbeatHandler().issueHeartbeat();
                fastMachine1.getHeartbeatHandler().doCheckView();
            }
            synchronized (lock(fastMachine2.getHeartbeatHandler())) {
                fastMachine2.getHeartbeatHandler().issueHeartbeat();
                fastMachine2.getHeartbeatHandler().doCheckView();
            }
            synchronized (lock(fastMachine3.getHeartbeatHandler())) {
                fastMachine3.getHeartbeatHandler().issueHeartbeat();
                fastMachine3.getHeartbeatHandler().doCheckView();
            }
            synchronized (lock(fastMachine4.getHeartbeatHandler())) {
                fastMachine4.getHeartbeatHandler().issueHeartbeat();
                fastMachine4.getHeartbeatHandler().doCheckView();
            }
        }
    }
    for (int i = 0; i < 4; i++) {
        hhSlow.issueHeartbeat();
        hhSlow.doCheckView();
        if (!scheduler) {
            synchronized (lock(fastMachine1.getHeartbeatHandler())) {
                fastMachine1.getHeartbeatHandler().issueHeartbeat();
                fastMachine1.getHeartbeatHandler().doCheckView();
            }
            synchronized (lock(fastMachine2.getHeartbeatHandler())) {
                fastMachine2.getHeartbeatHandler().issueHeartbeat();
                fastMachine2.getHeartbeatHandler().doCheckView();
            }
            synchronized (lock(fastMachine3.getHeartbeatHandler())) {
                fastMachine3.getHeartbeatHandler().issueHeartbeat();
                fastMachine3.getHeartbeatHandler().doCheckView();
            }
            synchronized (lock(fastMachine4.getHeartbeatHandler())) {
                fastMachine4.getHeartbeatHandler().issueHeartbeat();
                fastMachine4.getHeartbeatHandler().doCheckView();
            }
        }
        Thread.sleep(1000);
    }
    // now all should be in one cluster again
    assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, fastListener1.getLastEvent().getType());
    assertEquals(5, fastListener1.getLastEvent().getNewView().getInstances().size());
    assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, fastListener2.getLastEvent().getType());
    assertEquals(5, fastListener2.getLastEvent().getNewView().getInstances().size());
    assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, fastListener3.getLastEvent().getType());
    assertEquals(5, fastListener3.getLastEvent().getNewView().getInstances().size());
    assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, fastListener4.getLastEvent().getType());
    assertEquals(5, fastListener4.getLastEvent().getNewView().getInstances().size());
    assertEquals(TopologyEvent.Type.TOPOLOGY_CHANGED, slowListener.getLastEvent().getType());
    assertEquals(5, slowListener.getLastEvent().getNewView().getInstances().size());
    // SLING-5030 part 2 : after rejoin-after-partitioning the slowMachine1 should again be leader
    slowMachine.dumpRepo();
    assertFalse(slowListener.getLastEvent().getNewView().getLocalInstance().isLeader());
    assertTrue(fastListener1.getLastEvent().getNewView().getLocalInstance().isLeader());
    assertFalse(fastListener2.getLastEvent().getNewView().getLocalInstance().isLeader());
    assertFalse(fastListener3.getLastEvent().getNewView().getLocalInstance().isLeader());
    assertFalse(fastListener4.getLastEvent().getNewView().getLocalInstance().isLeader());
}
Also used : FullJR2VirtualInstanceBuilder(org.apache.sling.discovery.impl.setup.FullJR2VirtualInstanceBuilder) FullJR2VirtualInstance(org.apache.sling.discovery.impl.setup.FullJR2VirtualInstance) DiscoveryServiceImpl(org.apache.sling.discovery.impl.DiscoveryServiceImpl) TopologyView(org.apache.sling.discovery.TopologyView)

Aggregations

TopologyView (org.apache.sling.discovery.TopologyView)1 DiscoveryServiceImpl (org.apache.sling.discovery.impl.DiscoveryServiceImpl)1 FullJR2VirtualInstance (org.apache.sling.discovery.impl.setup.FullJR2VirtualInstance)1 FullJR2VirtualInstanceBuilder (org.apache.sling.discovery.impl.setup.FullJR2VirtualInstanceBuilder)1