package org.infinispan.executors;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.infinispan.test.AbstractInfinispanTest;
import org.infinispan.util.concurrent.BlockingRunnable;
import org.infinispan.util.concurrent.BlockingTaskAwareExecutorService;
import org.infinispan.util.concurrent.BlockingTaskAwareExecutorServiceImpl;
import org.testng.annotations.Test;
/**
* Simple executor test
*
* @author Pedro Ruivo
* @since 5.3
*/
@Test(groups = "functional", testName = "executors.BlockingTaskAwareExecutorServiceTest")
public class BlockingTaskAwareExecutorServiceTest extends AbstractInfinispanTest {
private static final AtomicInteger THREAD_ID = new AtomicInteger(0);
public void testSimpleExecution() throws Exception {
BlockingTaskAwareExecutorService executorService = createExecutorService();
try {
final DoSomething doSomething = new DoSomething();
executorService.execute(doSomething);
Thread.sleep(100);
assert !doSomething.isReady();
assert !doSomething.isExecuted();
doSomething.markReady();
executorService.checkForReadyTasks();
assert doSomething.isReady();
eventually(doSomething::isExecuted);
} finally {
executorService.shutdownNow();
}
}
public void testMultipleExecutions() throws Exception {
BlockingTaskAwareExecutorServiceImpl executorService = createExecutorService();
try {
List<DoSomething> tasks = new LinkedList<>();
for (int i = 0; i < 30; ++i) {
tasks.add(new DoSomething());
}
tasks.forEach(executorService::execute);
for (DoSomething doSomething : tasks) {
assert !doSomething.isReady();
assert !doSomething.isExecuted();
}
tasks.forEach(BlockingTaskAwareExecutorServiceTest.DoSomething::markReady);
executorService.checkForReadyTasks();
for (final DoSomething doSomething : tasks) {
eventually(doSomething::isExecuted);
}
} finally {
executorService.shutdownNow();
}
}
private BlockingTaskAwareExecutorServiceImpl createExecutorService() {
final String controllerName = "Controller-" + getClass().getSimpleName();
final ExecutorService realOne = new ThreadPoolExecutor(1, 2, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(),
new DummyThreadFactory());
return new BlockingTaskAwareExecutorServiceImpl(controllerName, realOne, TIME_SERVICE);
}
public static class DummyThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable runnable) {
return new Thread(runnable, "Remote-" + getClass().getSimpleName() + "-" + THREAD_ID.incrementAndGet());
}
}
public static class DoSomething implements BlockingRunnable {
private volatile boolean ready = false;
private volatile boolean executed = false;
@Override
public synchronized final boolean isReady() {
return ready;
}
@Override
public synchronized final void run() {
executed = true;
}
public synchronized final void markReady() {
ready = true;
}
public synchronized final boolean isExecuted() {
return executed;
}
}
}