package co.codewizards.cloudstore.core.concurrent;
import static java.lang.System.*;
import static org.assertj.core.api.Assertions.*;
import java.security.SecureRandom;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CallerBlocksPolicyTest {
private static Logger logger = LoggerFactory.getLogger(CallerBlocksPolicyTest.class);
private static Random random = new SecureRandom();
private final ThreadPoolExecutor executor = new ThreadPoolExecutor(0, 3,
60, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(2));
{
logger.debug("[{}]<init>", Integer.toHexString(identityHashCode(this)));
executor.setRejectedExecutionHandler(new CallerBlocksPolicy());
}
@Test
public void enqueueManyCallables() throws InterruptedException, ExecutionException {
logger.debug("[{}]enqueueManyCallables: entered.", Integer.toHexString(identityHashCode(this)));
final Set<Integer> indexesToDo = new HashSet<Integer>();
final Set<Integer> indexesDone = new HashSet<Integer>();
final List<Future<Void>> futures = new LinkedList<Future<Void>>();
for (int i = 0; i < 10; ++i) {
final int index = i;
indexesToDo.add(index);
logger.info("Submitting Callable[{}]...", index);
final Future<Void> future = executor.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
logger.info("[{}].begin", index);
Thread.sleep(1000 + random.nextInt(2000));
logger.info("[{}].end", index);
if (!indexesDone.add(index))
throw new IllegalStateException("index already added before: " + index);
return null;
}
});
logger.info("Submitted Callable[{}].", index);
futures.add(future);
}
logger.info("Waiting for all callables to finish...");
for (final Future<Void> future : futures) {
future.get();
}
logger.info("ALL DONE!");
assertThat(indexesDone).isEqualTo(indexesToDo);
}
}