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));
}
}
}
Aggregations