Search in sources :

Example 1 with VotingDetail

use of org.apache.sling.discovery.impl.cluster.voting.VotingHandler.VotingDetail in project sling by apache.

the class VotingHandlerTest method asyncVote.

private void asyncVote(final String debugInfo, final VotingHandler votingHandler, final List<VotingDetail> votingDetails, final Semaphore ready, final Semaphore go, final Semaphore done, final Set<Throwable> exceptions) throws Exception {
    Runnable r = new Runnable() {

        @Override
        public void run() {
            boolean released = false;
            try {
                logger.info("asyncVote[" + debugInfo + "] logging in...");
                Map<VotingView, VotingDetail> result = null;
                ResourceResolver rr = null;
                int retries = 0;
                while (true) {
                    try {
                        rr = factory.getServiceResourceResolver(null);
                        if (retries == 0) {
                            logger.info("asyncVote[" + debugInfo + "] marking ready...");
                            ready.release();
                            logger.info("asyncVote[" + debugInfo + "] waiting for go...");
                            go.acquire();
                        } else {
                            logger.info("asyncVote[" + debugInfo + "] not doing ready/go on retry.");
                        }
                        logger.info("asyncVote[" + debugInfo + "] analyzeVotings...");
                        result = votingHandler.analyzeVotings(rr);
                        break;
                    } catch (Exception e) {
                        logger.warn("asyncVote[" + debugInfo + "] Exception: " + e, e);
                        if (retries++ < 5) {
                            Thread.sleep(500);
                            logger.info("asyncVote[" + debugInfo + "] retrying after Exception...");
                            continue;
                        }
                        throw e;
                    } finally {
                        if (rr != null) {
                            rr.close();
                        }
                    }
                }
                logger.info("asyncVote[" + debugInfo + "] done, asserting results...");
                assertNotNull(result);
                votingDetails.addAll(result.values());
                logger.info("asyncVote[" + debugInfo + "] marking done.");
                done.release();
                released = true;
            } catch (RuntimeException re) {
                // SLING-5244: make sure we're not silently running into an unchecked exception
                logger.info("asyncVote[" + debugInfo + "] RuntimeException: " + re, re);
                exceptions.add(re);
                throw re;
            } catch (Error er) {
                // SLING-5244: make sure we're not silently running into an unchecked exception
                logger.info("asyncVote[" + debugInfo + "] Error: " + er, er);
                exceptions.add(er);
                throw er;
            } catch (Exception e) {
                // SLING-5244: make sure we're not silently running into an unchecked exception
                logger.info("asyncVote[" + debugInfo + "] Exception: " + e, e);
                exceptions.add(e);
            } finally {
                // SLING-5244: make sure we're getting informed when this thread is done - be it normal or not
                logger.info("asyncVote[" + debugInfo + "] finally [released=" + released + "]");
            }
        }
    };
    threadPool.execute(r);
}
Also used : ResourceResolver(org.apache.sling.api.resource.ResourceResolver) VotingDetail(org.apache.sling.discovery.impl.cluster.voting.VotingHandler.VotingDetail) PathNotFoundException(javax.jcr.PathNotFoundException)

Example 2 with VotingDetail

use of org.apache.sling.discovery.impl.cluster.voting.VotingHandler.VotingDetail in project sling by apache.

the class VotingHandlerTest method doTestConcurrentVotes.

public void doTestConcurrentVotes(int votingsLoopCnt, int perVotingInnerLoopCnt, VotingHandler... votingHandler) throws Exception {
    config.setHeartbeatInterval(999);
    config.setHeartbeatTimeout(120);
    for (VotingHandler handler : votingHandler) {
        handler.activate(null);
    }
    int[] totals = new int[votingHandler.length];
    List<Map<VotingDetail, Integer>> totalDetails = new LinkedList<Map<VotingDetail, Integer>>();
    for (int i = 0; i < votingHandler.length; i++) {
        HashMap<VotingDetail, Integer> d = new HashMap<VotingHandler.VotingDetail, Integer>();
        totalDetails.add(d);
    }
    String[] slingIds = new String[votingHandler.length];
    for (int k = 0; k < votingHandler.length; k++) {
        slingIds[k] = (String) PrivateAccessor.getField(votingHandler[k], "slingId");
    }
    for (int i = 0; i < votingsLoopCnt; i++) {
        // large voting loop
        logger.info("testConcurrentVotes: loop i=" + i + ", votingHandler.cnt=" + votingHandler.length);
        for (int k = 0; k < votingHandler.length; k++) {
            heartbeat(slingIds[k]);
        }
        for (int k = 0; k < votingHandler.length; k++) {
            String initiatorId = (String) PrivateAccessor.getField(votingHandler[k], "slingId");
            VotingView voting = newVoting(initiatorId, slingIds);
            assertNotNull(voting);
        }
        Semaphore ready = new Semaphore(0);
        Semaphore go = new Semaphore(0);
        Semaphore done = new Semaphore(0);
        Set<Throwable> e = new ConcurrentHashSet<Throwable>();
        boolean success = false;
        List<List<VotingDetail>> detailList = new LinkedList<List<VotingDetail>>();
        for (int k = 0; k < votingHandler.length; k++) {
            detailList.add(new LinkedList<VotingHandler.VotingDetail>());
        }
        for (int j = 0; j < perVotingInnerLoopCnt; j++) {
            logger.info("testConcurrentVotes: loop i=" + i + ", votingHandler.cnt=" + votingHandler.length + ", j=" + j);
            for (int k = 0; k < votingHandler.length; k++) {
                logger.info("testConcurrentVotes: <heartbeat for slingId,k=" + k + "> loop i=" + i + ", votingHandler.cnt=" + votingHandler.length + ", j=" + j);
                heartbeat(slingIds[k]);
                logger.info("testConcurrentVotes: <asyncVote for slingId,k=" + k + "> loop i=" + i + ", votingHandler.cnt=" + votingHandler.length + ", j=" + j);
                asyncVote("k=" + k, votingHandler[k], detailList.get(k), ready, go, done, e);
            }
            assertTrue("threads were not ready within 30sec", ready.tryAcquire(votingHandler.length, 30, TimeUnit.SECONDS));
            // both are now ready, so lets go
            logger.info("testConcurrentVotes: GO loop i=" + i + ", votingHandler.cnt=" + votingHandler.length + ", j=" + j);
            go.release(votingHandler.length);
            assertTrue("threads were not done within 120sec", done.tryAcquire(votingHandler.length, 120, TimeUnit.SECONDS));
            if (e.size() != 0) {
                fail("Got exceptions: " + e.size() + ", first: " + e.iterator().next());
            }
            int promotionTotalCount = 0;
            int noTotalCount = 0;
            for (int k = 0; k < votingHandler.length; k++) {
                int promotedCnt = count(detailList.get(k), VotingDetail.PROMOTED);
                int noCnt = count(detailList.get(k), VotingDetail.VOTED_NO);
                totals[k] += promotedCnt;
                promotionTotalCount += promotedCnt;
                noTotalCount += noCnt;
            }
            if (promotionTotalCount == 0) {
                // should have 1 promotionTotalCount, if not, repeat
                continue;
            } else if (promotionTotalCount > 1) {
                fail("more than 1 promoted views: " + promotionTotalCount);
            } else if (noTotalCount < votingHandler.length - 1) {
                // should have votingHandler.length-1 no votes, if not, repeat
                continue;
            } else {
                // done
                success = true;
                break;
            }
        }
        assertTrue("did not promote within " + perVotingInnerLoopCnt + " loops", success);
        for (int k = 0; k < votingHandler.length; k++) {
            add(detailList.get(k), totalDetails.get(k));
        }
    }
    StringBuffer sb = new StringBuffer();
    for (int k = 0; k < votingHandler.length; k++) {
        sb.append(" - by slingId");
        sb.append(k + 1);
        sb.append(": ");
        sb.append(totals[k]);
    }
    logger.info("testConcurrentVotes: promoted " + sb);
    int totalPromotion = 0;
    for (int k = 0; k < votingHandler.length; k++) {
        for (Map.Entry<VotingDetail, Integer> anEntry : totalDetails.get(k).entrySet()) {
            logger.info("testConcurrentVotes: slingId" + (k + 1) + ", detail=" + anEntry.getKey() + ", value=" + anEntry.getValue());
        }
        // SLING-5244 : cannot assume that we have '(votingHandler.length-1) * votingsLoopCnt'
        // because: it can happen that a voting concludes within one j-loop above:
        // that is the case when the instance that does not initiate the vote comes first, then
        // the initiator - in that case the initiator finds an already completed vote - and it
        // will then not do any no-votes ..
        // so .. this check is a) not possible and b) just also not necessary, cos
        // we already make sure that we at least get 'votingHandler.length-1' no votes in the j-loop
        // and that is precise enough. so as unfortuante as it is, we can't make below assertion..
        // unless we do more white-box-assertions into analyzeVotings, which is probably not helping
        // test-stability either..
        //            Integer noVotes = totalDetails.get(k).get(VotingDetail.VOTED_NO);
        //            int expected = (votingHandler.length-1) * votingsLoopCnt;
        //            if (expected>0) {
        //                assertEquals(expected, (int)noVotes);
        //            }
        final Map<VotingDetail, Integer> map = totalDetails.get(k);
        final Integer i = map.get(VotingDetail.PROMOTED);
        if (i != null) {
            totalPromotion += i;
        }
    }
    assertEquals(votingsLoopCnt, totalPromotion);
}
Also used : HashMap(java.util.HashMap) Semaphore(java.util.concurrent.Semaphore) LinkedList(java.util.LinkedList) ConcurrentHashSet(org.eclipse.jetty.util.ConcurrentHashSet) VotingDetail(org.apache.sling.discovery.impl.cluster.voting.VotingHandler.VotingDetail) LinkedList(java.util.LinkedList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with VotingDetail

use of org.apache.sling.discovery.impl.cluster.voting.VotingHandler.VotingDetail in project sling by apache.

the class VotingHandlerTest method add.

private void add(List<VotingDetail> votingDetails, Map<VotingDetail, Integer> totals) {
    for (VotingDetail d : votingDetails) {
        Integer i = totals.get(d);
        if (i == null) {
            i = 0;
        }
        i++;
        totals.put(d, i);
    }
}
Also used : VotingDetail(org.apache.sling.discovery.impl.cluster.voting.VotingHandler.VotingDetail)

Aggregations

VotingDetail (org.apache.sling.discovery.impl.cluster.voting.VotingHandler.VotingDetail)3 HashMap (java.util.HashMap)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Map (java.util.Map)1 Semaphore (java.util.concurrent.Semaphore)1 PathNotFoundException (javax.jcr.PathNotFoundException)1 ResourceResolver (org.apache.sling.api.resource.ResourceResolver)1 ConcurrentHashSet (org.eclipse.jetty.util.ConcurrentHashSet)1