Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,24 @@
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.tea.core.internal.TaskProgressEstimationService;
import org.eclipse.tea.core.internal.TaskingEngineActivator;
import org.eclipse.tea.core.internal.model.TaskingModel;
import org.eclipse.tea.core.services.TaskProgressTracker;
import org.eclipse.tea.core.services.TaskProgressTracker.TaskProgressProvider;

public class BackgroundTask {

private static final ExecutorService backgroundTasks = Executors
.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

private final Object task;
private Future<?> future;
private Future<IStatus> future;

public BackgroundTask(Object task) {
Object actualTask;
Expand All @@ -44,52 +50,121 @@ public BackgroundTask(Object task) {
this.task = actualTask;
}

private static final TaskProgressTracker EMPTY_PROGRESS_TRACKER = new TaskProgressTracker() {

@Override
public void worked(int amount) {

}

@Override
public boolean isCanceled() {
return false;
}

@Override
public void setTaskName(String name) {

}
};

@Execute
public void run(IEclipseContext context) throws Exception {
future = backgroundTasks.submit(() -> {
IEclipseContext taskCtx = context.createChild();
ContextInjectionFactory.invoke(task, Execute.class, context);
return taskCtx.get(IStatus.class);
});
}

public Object barrier() {
return new Object() {
@Execute
public Object doWait() throws Exception {
return future.get();
public Object doWait(TaskProgressEstimationService progressService, TaskProgressTracker rootTracker)
throws Exception {
String estimationId = progressService.calculateId(task);
if (estimationId != null) {
progressService.begin(estimationId, EMPTY_PROGRESS_TRACKER);
}
Future<?> ticker = tickProgressTracker(rootTracker, getWork(progressService));
IStatus taskStatus = future.get();
if (estimationId != null) {
progressService.finish(estimationId, taskStatus);
}
ticker.cancel(true);
return taskStatus;
}

@Override
public String toString() {
return "Wait for: " + BackgroundTask.this.toString();
}

@TaskProgressProvider
public int getWork(TaskProgressEstimationService progressService) {
String estimationId = progressService.calculateId(task);
return estimationId == null ? 1 : progressService.getEstimatedTicks(estimationId);
}
};
}

public static Object allBarrier(List<Object> tasks) {
List<BackgroundTask> toAwait = new ArrayList<>();
int hash = 0;
for (Object task : tasks) {
if (task instanceof BackgroundTask) {
toAwait.add((BackgroundTask) task);
hash ^= ((BackgroundTask) task).task.getClass().getName().hashCode();
}
}
if (toAwait.isEmpty()) {
return null;
}
String estimationId = "await_async_" + tasks.size() + "_" + hash;

return new Object() {
@Execute
public void doWaitAll(IEclipseContext context) throws Exception {
public void doWaitAll(IEclipseContext context, TaskProgressTracker tracker,
TaskProgressEstimationService progressService) throws Exception {
Future<?> ticker = tickProgressTracker(tracker, getWork(progressService));
progressService.begin(estimationId, EMPTY_PROGRESS_TRACKER);
int severity = 0;
Comment thread
haubi marked this conversation as resolved.
for (BackgroundTask bt : toAwait) {
bt.future.get();
severity |= bt.future.get().getSeverity();
}
progressService.finish(estimationId, new Status(severity, TaskingEngineActivator.PLUGIN_ID,
"Finished waiting for background tasks."));
ticker.cancel(true);
}

@Override
public String toString() {
return "Await unfinished background tasks.";
}

@TaskProgressProvider
public int getWork(TaskProgressEstimationService progressService) {
return progressService.getEstimatedTicks(estimationId);
}
};
}

private static Future<?> tickProgressTracker(TaskProgressTracker rootTracker, long estimationTicks) {
int resolution = 100;
return backgroundTasks.submit(() -> {
long remaining = estimationTicks;
while (remaining > 0) {
try {
Thread.sleep(resolution);
} catch (InterruptedException e) {
return; // expected if task completes earlier
}
rootTracker.worked(1);
remaining--;
}
});
}

@Override
public String toString() {
return TaskingModel.getTaskName(task) + " (parallel)";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.tea.core.services.TaskProgressTracker;
import org.eclipse.tea.core.services.TaskProgressTracker.TaskProgressProvider;
import org.eclipse.tea.library.build.model.WorkspaceData;

/**
Expand All @@ -29,6 +30,11 @@
@Named("Clean and refresh all projects") // Progress Monitor shows & as _
public class TaskCleanWorkspace {

@TaskProgressProvider
public int getWork() {
return ResourcesPlugin.getWorkspace().getRoot().getProjects().length;
}

@Execute
public void run(TaskProgressTracker tracker) throws Exception {
// refresh all projects
Expand Down
Loading