in src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java [809:931]
private ACTION doExecuteTasks(final SortedSet<InstallTask> tasks) {
if ( !tasks.isEmpty() ) {
final InstallationContext ctx = new InstallationContext() {
@Override
public void addTaskToNextCycle(final InstallTask t) {
logger.warn("Deprecated method addTaskToNextCycle was called. Task will be executed in this cycle instead: {}", t);
synchronized ( tasks ) {
tasks.add(t);
}
}
@Override
public void addTaskToCurrentCycle(final InstallTask t) {
logger.debug("Adding {}task to current cycle: {}", t.isAsynchronousTask() ? "async " : "", t);
synchronized ( tasks ) {
tasks.add(t);
}
}
@Override
public void addAsyncTask(final InstallTask t) {
if ( t.isAsynchronousTask() ) {
logger.warn("Deprecated method addAsyncTask was called: {}", t);
this.addTaskToCurrentCycle(t);
} else {
logger.warn("Deprecated method addAsyncTask is called with non async task(!): {}", t);
this.addTaskToCurrentCycle(new AsyncWrapperInstallTask(t));
}
}
@Override
public void log(final String message, final Object... args) {
auditLogger.info(message, args);
}
@Override
public void asyncTaskFailed(final InstallTask t) {
// persist all changes and retry restart
// remove attribute
logger.debug("asyncTaskFailed: {}", t);
if ( t.getResource() != null ) {
t.getResource().setAttribute(InstallTask.ASYNC_ATTR_NAME, null);
}
persistentList.save();
synchronized ( resourcesLock ) {
if ( !active ) {
logger.debug("Restarting background thread from asyncTaskFailed");
active = true;
startBackgroundThread();
} else {
logger.debug("active={}, no need to restart background thread", active);
}
}
}
};
while (this.active && !tasks.isEmpty()) {
InstallTask task = null;
synchronized (tasks) {
task = tasks.first();
tasks.remove(task);
}
// async tasks are executed "immediately"
if ( task.isAsynchronousTask() ) {
logger.debug("Executing async task: {}", task);
// set attribute
final Integer oldValue;
if ( task.getResource() != null ) {
oldValue = (Integer)task.getResource().getAttribute(InstallTask.ASYNC_ATTR_NAME);
final Integer newValue;
if ( oldValue == null ) {
newValue = 1;
} else {
newValue = oldValue + 1;
}
task.getResource().setAttribute(InstallTask.ASYNC_ATTR_NAME, newValue);
} else {
oldValue = null;
}
// save new state
this.cleanupInstallableResources();
final InstallTask aSyncTask = task;
final String threadName = "BackgroundTaskThread" + backgroundTaskCounter.incrementAndGet();
final Thread t = new Thread(threadName) {
@Override
public void run() {
logger.debug("Starting background thread {} to execute {}",
Thread.currentThread().getName(),
aSyncTask);
try {
Thread.sleep(2000L);
} catch (final InterruptedException ie) {
// ignore
}
// reset attribute
if ( aSyncTask.getResource() != null ) {
aSyncTask.getResource().setAttribute(InstallTask.ASYNC_ATTR_NAME, oldValue);
}
aSyncTask.execute(ctx);
logger.debug("Background thread {} ends", Thread.currentThread().getName());
}
};
t.start();
return ACTION.SHUTDOWN;
}
try {
logger.debug("Executing task: {}", task);
task.execute(ctx);
} catch (final Throwable t) {
logger.error("Uncaught exception during task execution!", t);
}
}
// save new state
final boolean newCycle = this.cleanupInstallableResources();
if ( newCycle ) {
return ACTION.CYCLE;
}
}
return ACTION.SLEEP;
}