Search in sources :

Example 1 with ScheduleDelayMode

use of alma.acs.concurrent.ThreadLoopRunner.ScheduleDelayMode in project ACS by ACS-Community.

the class ThreadLoopRunnerTest method testComplexWithSuspendAndRestart.

/**
	 * Tests a well-behaved but complex usage scenario, 
	 * including calls to suspend and start again the execution loop.
	 */
public void testComplexWithSuspendAndRestart() throws Exception {
    int actionWaitMillis = 100;
    int delayMillis = 300;
    int numberOnOffCycles = 3;
    int expectedInvocationsPerCycle = 33;
    int allowedThreadJitterMillis = 200;
    CountDownLatch sync = new CountDownLatch(expectedInvocationsPerCycle);
    MyAction myAction = new MyAction(sync, actionWaitMillis, logger);
    ThreadLoopRunner threadLoopRunner = null;
    try {
        threadLoopRunner = new ThreadLoopRunner(myAction, delayMillis, TimeUnit.MILLISECONDS, tf, logger, "testComplex");
        StopWatch sw = new StopWatch();
        for (int i = 0; i < numberOnOffCycles; i++) {
            ScheduleDelayMode delayMode = i % 2 == 0 ? ScheduleDelayMode.FIXED_RATE : ScheduleDelayMode.FIXED_DELAY;
            logger.info("Will start the thread loop with delay mode " + delayMode.toString());
            threadLoopRunner.setDelayMode(delayMode);
            threadLoopRunner.runLoop();
            sw.reset();
            // wait till the last execution of the action is over
            int expectedDurationMillis = (expectedInvocationsPerCycle - 1) * delayMillis + actionWaitMillis;
            if (delayMode == ScheduleDelayMode.FIXED_DELAY) {
                expectedDurationMillis += (expectedInvocationsPerCycle - 1) * actionWaitMillis;
            }
            int timeoutMillis = expectedDurationMillis + allowedThreadJitterMillis + 1000;
            boolean awaitRet = sync.await(timeoutMillis, TimeUnit.MILLISECONDS);
            int actualDuration = (int) sw.getLapTimeMillis();
            int actualInvocations = myAction.getCount();
            assertTrue("Timed out after " + timeoutMillis + " ms", awaitRet);
            assertEquals(expectedInvocationsPerCycle, actualInvocations);
            assertTrue("Tasks were run faster (" + actualDuration + ") than expected (" + expectedDurationMillis + ")", actualDuration > expectedDurationMillis - allowedThreadJitterMillis);
            assertTrue(threadLoopRunner.isLoopRunning());
            assertFalse(threadLoopRunner.isDisabled());
            // suspend and assert that no further actions get executed 
            logger.info("Will suspend the thread loop");
            threadLoopRunner.suspendLoop();
            assertFalse(threadLoopRunner.isLoopRunning());
            assertFalse(threadLoopRunner.isDisabled());
            assertEquals(delayMode, threadLoopRunner.getDelayMode());
            Thread.sleep((actionWaitMillis + delayMillis) * 2);
            assertEquals(expectedInvocationsPerCycle, myAction.getCount());
            // run again
            sync = new CountDownLatch(expectedInvocationsPerCycle);
            myAction.reset(sync);
        }
    } finally {
        if (threadLoopRunner != null) {
            assertTrue(threadLoopRunner.shutdown(100, TimeUnit.MILLISECONDS));
        }
    }
}
Also used : ScheduleDelayMode(alma.acs.concurrent.ThreadLoopRunner.ScheduleDelayMode) CountDownLatch(java.util.concurrent.CountDownLatch) StopWatch(alma.acs.util.StopWatch)

Aggregations

ScheduleDelayMode (alma.acs.concurrent.ThreadLoopRunner.ScheduleDelayMode)1 StopWatch (alma.acs.util.StopWatch)1 CountDownLatch (java.util.concurrent.CountDownLatch)1