*
* @param is
* If non-null, this can be consulted for ignoring some tasks. Only used during the initialization of Hudson.
*/
private void executeReactor(final InitStrategy is, TaskBuilder... builders) throws IOException, InterruptedException, ReactorException {
Reactor reactor = new Reactor(builders) {
/**
* Sets the thread name to the task for better diagnostics.
*/
@Override
protected void runTask(Task task) throws Exception {
if (is != null && is.skipInitTask(task)) {
return;
}
SecurityContextHolder.getContext().setAuthentication(ACL.SYSTEM); // full access in the initialization thread
String taskName = task.getDisplayName();
Thread t = Thread.currentThread();
String name = t.getName();
if (taskName != null) {
t.setName(taskName);
}
try {
long start = System.currentTimeMillis();
super.runTask(task);
if (LOG_STARTUP_PERFORMANCE) {
LOGGER.info(String.format("Took %dms for %s by %s",
System.currentTimeMillis() - start, taskName, name));
}
} finally {
t.setName(name);
SecurityContextHolder.clearContext();
}
}
};
ExecutorService es;
if (PARALLEL_LOAD) {
es = new ThreadPoolExecutor(
TWICE_CPU_NUM, TWICE_CPU_NUM, 5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new DaemonThreadFactory());
} else {
es = Executors.newSingleThreadExecutor(new DaemonThreadFactory());
}
try {
reactor.execute(es, buildReactorListener());
} finally {
es.shutdownNow(); // upon a successful return the executor queue should be empty. Upon an exception, we want to cancel all pending tasks
}
}