Maven: removed unnecessary threads + lost readAction

This commit is contained in:
Anton.Makeev
2009-11-09 11:42:39 +03:00
parent e65f220fbd
commit 5a2ce276f9
5 changed files with 122 additions and 187 deletions
@@ -16,70 +16,63 @@
package org.jetbrains.idea.maven.project;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.util.concurrency.Semaphore;
import org.jetbrains.idea.maven.embedder.MavenConsole;
import org.jetbrains.idea.maven.execution.SoutMavenConsole;
import org.jetbrains.idea.maven.utils.*;
import org.jetbrains.idea.maven.utils.MavenProcessCanceledException;
import org.jetbrains.idea.maven.utils.MavenProgressIndicator;
import org.jetbrains.idea.maven.utils.MavenTask;
import org.jetbrains.idea.maven.utils.MavenUtil;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.LinkedList;
import java.util.Queue;
public class MavenProjectsProcessor {
private static final int WAIT_TIMEOUT = 2000;
private final Project myProject;
private final String myTitle;
private final boolean myCancellable;
private final MavenEmbeddersManager myEmbeddersManager;
private final Thread myThread;
private final BlockingQueue<MavenProjectsProcessorTask> myQueue = new LinkedBlockingQueue<MavenProjectsProcessorTask>();
private final Queue<MavenProjectsProcessorTask> myQueue = new LinkedList<MavenProjectsProcessorTask>();
private boolean isProcessing;
private volatile boolean isStopped;
private volatile MavenUtil.MavenTaskHandler myCurrentTaskHandler;
public MavenProjectsProcessor(Project project, String title, boolean cancellable, MavenEmbeddersManager embeddersManager) {
myProject = project;
myTitle = title;
myCancellable = cancellable;
myEmbeddersManager = embeddersManager;
myThread = new Thread(new Runnable() {
public void run() {
try {
while (doRunCycle()) { /* nothing */ }
}
catch (Throwable e) {
MavenLog.LOG.error(e);
throw new RuntimeException(e);
}
}
}, getClass().getSimpleName() + ": " + title);
if (isImmediateMode()) return;
isStopped = false;
myThread.start(); // rework if make inheritance
}
public void scheduleTask(MavenProjectsProcessorTask task) {
synchronized (myQueue) {
if (!isProcessing && !MavenUtil.isNoBackgroundMode()) {
isProcessing = true;
startProcessing(task);
return;
}
if (myQueue.contains(task)) return;
myQueue.add(task);
myQueue.notifyAll();
}
}
public void removeTask(MavenProjectsProcessorTask task) {
synchronized (myQueue) {
myQueue.remove(task);
myQueue.notifyAll();
}
}
public void waitForCompletion() {
if (isEmpty()) return;
if (isStopped) return;
if (isImmediateMode()) {
while (!isEmpty() && doRunCycle()) {/* do nothing */}
if (MavenUtil.isNoBackgroundMode()) {
synchronized (myQueue) {
while (!myQueue.isEmpty()) {
startProcessing(myQueue.poll());
}
}
return;
}
@@ -93,94 +86,67 @@ public class MavenProjectsProcessor {
});
while (true) {
if (isStopped || isEmpty() || semaphore.waitFor(WAIT_TIMEOUT)) return;
}
}
private boolean isEmpty() {
synchronized (myQueue) {
return myQueue.isEmpty();
}
}
private void cancelAllPendingRequests() {
synchronized (myQueue) {
myQueue.clear();
myQueue.notifyAll();
if (isStopped || semaphore.waitFor(1000)) return;
}
}
public void stop() {
if (isImmediateMode()) return;
isStopped = true;
synchronized (myQueue) {
myQueue.notifyAll();
myQueue.clear();
}
cancelAllPendingRequests();
MavenUtil.MavenTaskHandler handler = myCurrentTaskHandler;
if (handler != null) handler.stop();
//myThread.join();
}
public boolean doRunCycle() {
try {
synchronized (myQueue) {
while (myQueue.isEmpty()) {
myQueue.wait(WAIT_TIMEOUT);
if (isStopped) return false;
}
}
}
catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (isStopped) return false;
myCurrentTaskHandler = MavenUtil.runInBackground(myProject, myTitle, myCancellable, new MavenTask() {
private void startProcessing(final MavenProjectsProcessorTask task) {
MavenUtil.runInBackground(myProject, myTitle, myCancellable, new MavenTask() {
public void run(MavenProgressIndicator indicator) throws MavenProcessCanceledException {
int counter = 0;
while (true) {
MavenProjectsProcessorTask task;
int queueSize;
synchronized (myQueue) {
task = myQueue.peek();
queueSize = myQueue.size();
}
if (isStopped || task == null) return;
try {
indicator.checkCanceled();
counter++;
indicator.setFraction(counter / (double)(counter + queueSize));
String text = myTitle;
if (queueSize > 0) text += " (" + (queueSize + 1) + " in queue)";
indicator.setText(text);
task.perform(myProject, myEmbeddersManager, new SoutMavenConsole(), indicator);
}
finally {
synchronized (myQueue) {
myQueue.remove(task); // remove the completed task from the queue
}
Condition<MavenProgressIndicator> condition = new Condition<MavenProgressIndicator>() {
public boolean value(MavenProgressIndicator mavenProgressIndicator) {
return isStopped;
}
};
indicator.addCancelCondition(condition);
try {
doProcessPendingTasks(indicator, task);
}
finally {
indicator.removeCancelCondition(condition);
}
}
});
myCurrentTaskHandler.waitFor();
if (myCurrentTaskHandler.isCancelled()) {
cancelAllPendingRequests();
}
myCurrentTaskHandler = null;
return !isStopped;
}
private boolean isImmediateMode() {
return MavenUtil.isNoBackgroundMode();
private void doProcessPendingTasks(MavenProgressIndicator indicator, MavenProjectsProcessorTask task)
throws MavenProcessCanceledException {
int counter = 0;
try {
while (true) {
indicator.checkCanceled();
counter++;
int remained;
synchronized (myQueue) {
remained = myQueue.size();
}
indicator.setFraction(counter / (double)(counter + remained));
task.perform(myProject, myEmbeddersManager, new SoutMavenConsole(), indicator);
synchronized (myQueue) {
task = myQueue.poll();
if (task == null) {
isProcessing = false;
return;
}
}
}
}
catch (MavenProcessCanceledException e) {
synchronized (myQueue) {
myQueue.clear();
isProcessing = false;
}
throw e;
}
}
}
@@ -15,7 +15,9 @@
*/
package org.jetbrains.idea.maven.utils;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
@@ -29,8 +31,12 @@ public class MavenProblemFileHighlighter implements Condition<VirtualFile> {
myProject = project;
}
public boolean value(VirtualFile file) {
PsiFile psiFile = PsiManager.getInstance(myProject).findFile(file);
return psiFile != null && MavenDomUtil.isMavenFile(psiFile);
public boolean value(final VirtualFile file) {
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
public Boolean compute() {
PsiFile psiFile = PsiManager.getInstance(myProject).findFile(file);
return psiFile != null && MavenDomUtil.isMavenFile(psiFile);
}
});
}
}
@@ -18,88 +18,65 @@ package org.jetbrains.idea.maven.utils;
import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.openapi.util.Condition;
import java.util.ArrayList;
import java.util.List;
public class MavenProgressIndicator {
private final List<ProgressIndicator> myIndicators = ContainerUtil.createEmptyCOWList();
private String myText;
private String myText2;
private double myFraction;
private boolean myCanceled;
private ProgressIndicator myIndicator;
private List<Condition<MavenProgressIndicator>> myCancelConditions = new ArrayList<Condition<MavenProgressIndicator>>();
public MavenProgressIndicator() {
this(new EmptyProgressIndicator());
}
public MavenProgressIndicator(ProgressIndicator i) {
myText = i.getText();
myText2 = i.getText2();
myFraction = i.getFraction();
myCanceled = i.isCanceled();
addIndicator(i);
myIndicator = i;
}
public void addIndicator(ProgressIndicator i) {
synchronized (this) {
i.setText(myText);
i.setText2(myText2);
i.setFraction(myFraction);
if (myCanceled) i.cancel();
}
myIndicators.add(i);
public synchronized void setIndicator(ProgressIndicator i) {
i.setText(myIndicator.getText());
i.setText2(myIndicator.getText2());
i.setFraction(myIndicator.getFraction());
if (i.isCanceled()) i.cancel();
myIndicator = i;
}
public ProgressIndicator getIndicator() {
return myIndicators.isEmpty() ? new EmptyProgressIndicator() : myIndicators.get(0);
public synchronized ProgressIndicator getIndicator() {
return myIndicator;
}
public void setText(String text) {
synchronized (this) {
myText = text;
}
for (ProgressIndicator each : myIndicators) {
each.setText(text);
}
public synchronized void setText(String text) {
myIndicator.setText(text);
}
public void setText2(String text) {
synchronized (this) {
myText2 = text;
}
for (ProgressIndicator each : myIndicators) {
each.setText2(text);
}
public synchronized void setText2(String text) {
myIndicator.setText2(text);
}
public void setFraction(double fraction) {
synchronized (this) {
myFraction = fraction;
}
for (ProgressIndicator each : myIndicators) {
each.setFraction(fraction);
}
public synchronized void setFraction(double fraction) {
myIndicator.setFraction(fraction);
}
public void cancel() {
synchronized (this) {
myCanceled = true;
}
for (ProgressIndicator each : myIndicators) {
each.cancel();
}
public synchronized void cancel() {
myIndicator.cancel();
}
public boolean isCanceled() {
for (ProgressIndicator each : myIndicators) {
if (each.isCanceled()) {
synchronized (this) {
myCanceled = true;
}
break;
}
public synchronized void addCancelCondition(Condition<MavenProgressIndicator> condition) {
myCancelConditions.add(condition);
}
public synchronized void removeCancelCondition(Condition<MavenProgressIndicator> condition) {
myCancelConditions.remove(condition);
}
public synchronized boolean isCanceled() {
if (myIndicator.isCanceled()) return true;
for (Condition<MavenProgressIndicator> each : myCancelConditions) {
if (each.value(this)) return true;
}
return myCanceled;
return false;
}
public void checkCanceled() throws MavenProcessCanceledException {
@@ -432,14 +432,14 @@ public class MavenUtil {
if (isNoBackgroundMode()) {
runnable.run();
return new MavenTaskHandler(indicator) {
return new MavenTaskHandler() {
public void waitFor() {
}
};
}
else {
final Future<?> future = ApplicationManager.getApplication().executeOnPooledThread(runnable);
final MavenTaskHandler handler = new MavenTaskHandler(indicator) {
final MavenTaskHandler handler = new MavenTaskHandler() {
public void waitFor() {
try {
future.get();
@@ -457,7 +457,7 @@ public class MavenUtil {
if (future.isDone()) return;
new Task.Backgroundable(project, title, cancellable) {
public void run(@NotNull ProgressIndicator i) {
indicator.addIndicator(i);
indicator.setIndicator(i);
handler.waitFor();
}
}.queue();
@@ -467,21 +467,7 @@ public class MavenUtil {
}
}
public static abstract class MavenTaskHandler {
private final MavenProgressIndicator myIndicator;
private MavenTaskHandler(MavenProgressIndicator indicator) {
myIndicator = indicator;
}
public void stop() {
myIndicator.cancel();
}
public abstract void waitFor();
public boolean isCancelled() {
return myIndicator.isCanceled();
}
public interface MavenTaskHandler {
void waitFor();
}
}
@@ -2,17 +2,17 @@ maven.name=Maven
maven.scanning.projects=Scanning Maven projects
maven.locating.files=Locating Maven project files
maven.searching.profiles=Looking for available profiles
maven.reading=Reading
maven.reading=Reading Maven projects
maven.reading.pom=Reading {0}
maven.resolving=Resolving dependencies
maven.resolving=Resolving Maven dependencies
maven.resolving.finished=Finished resolving dependencies
maven.resolving.pom=Resolving dependencies of {0}
maven.updating.folders=Generating sources
maven.updating.folders=Generating Maven sources
maven.updating.folders.finished=Finished Generating sources
maven.updating.folders.pom=Generating sources for {0}
maven.downloading.plugins=Downloading plugins
maven.downloading.plugins=Downloading Maven plugins
maven.downloading.pom.plugins=Downloading plugins for {0}
maven.downloading=Downloading sources and javadocs
maven.downloading=Downloading Maven sources and javadocs
maven.downloading.finished=Finished downloading artifacts
maven.downloading.artifact=Downloading {0}
maven.transfer.progress={0}/{1}K [{2}] {3}