make DumbService control flow a bit clearer (imho)

This commit is contained in:
peter
2012-10-11 20:21:49 +02:00
parent 1599162ebd
commit 2573e83aee
@@ -40,6 +40,7 @@ import com.intellij.util.io.storage.HeavyProcessLatch;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
@@ -299,7 +300,6 @@ public class DumbServiceImpl extends DumbService {
public void run() {
ProgressManager.getInstance().run(new Task.Backgroundable(myProject, IdeBundle.message("progress.indexing"), false) {
private final BlockingQueue<Ref<CacheUpdateRunner>> myActionQueue = new LinkedBlockingQueue<Ref<CacheUpdateRunner>>();
@Override
public void run(@NotNull final ProgressIndicator indicator) {
@@ -347,6 +347,10 @@ public class DumbServiceImpl extends DumbService {
shutdownTracker.registerStopperThread(self);
runAction(proxy, myAction);
}
catch (RuntimeException e) {
LOG.debug(e);
throw e;
}
finally {
shutdownTracker.unregisterStopperThread(self);
HeavyProcessLatch.INSTANCE.processFinished();
@@ -354,80 +358,66 @@ public class DumbServiceImpl extends DumbService {
}
private void runAction(ProgressIndicator indicator, CacheUpdateRunner updateRunner) {
do {
int count = 0;
try {
indicator.setIndeterminate(true);
indicator.setText(IdeBundle.message("progress.indexing.scanning"));
count = updateRunner.queryNeededFiles(indicator);
while (updateRunner != null) {
indicator.setIndeterminate(true);
indicator.setText(IdeBundle.message("progress.indexing.scanning"));
int count = updateRunner.queryNeededFiles(indicator);
myCurrentBaseTotal = count;
myTotalItems += count;
myCurrentBaseTotal = count;
myTotalItems += count;
indicator.setIndeterminate(false);
indicator.setText(IdeBundle.message("progress.indexing.updating"));
if (count > 0) {
updateRunner.processFiles(indicator, true);
}
updateRunner.updatingDone();
}
finally {
myProcessedItems += count;
if (LOG.isDebugEnabled()) {
LOG.debug("Scheduling checkNextUpdateFromQueue; Thread: " + Thread.currentThread().getName());
}
UIUtil.invokeLaterIfNeeded(new DumbAwareRunnable() {
public void run() {
checkNextUpdateFromQueue();
}
});
// try to obtain the next action or terminate if no actions left
Ref<CacheUpdateRunner> ref = null;
do {
try {
ref = myActionQueue.poll(500, TimeUnit.MILLISECONDS);
}
catch (InterruptedException e) {
LOG.info(e);
}
updateRunner = ref != null? ref.get() : null;
if (myProject.isDisposed()) {
// just terminate the progress task
break;
}
}
while (ref == null);
indicator.setIndeterminate(false);
indicator.setText(IdeBundle.message("progress.indexing.updating"));
if (count > 0) {
updateRunner.processFiles(indicator, true);
}
updateRunner.updatingDone();
myProcessedItems += count;
updateRunner = getNextUpdateRunner();
}
while (updateRunner != null);
}
private void checkNextUpdateFromQueue() {
if (LOG.isDebugEnabled()) {
LOG.debug("Inside checkNextUpdateFromQueue, Thread: " + Thread.currentThread().getName());
@Nullable
private CacheUpdateRunner getNextUpdateRunner() {
final BlockingQueue<Ref<CacheUpdateRunner>> actionQueue = new LinkedBlockingQueue<Ref<CacheUpdateRunner>>();
UIUtil.invokeLaterIfNeeded(new DumbAwareRunnable() {
public void run() {
IndexUpdateRunnable nextRunnable = getNextUpdateFromQueue();
try {
actionQueue.offer(nextRunnable == null ? NULL_ACTION : new Ref<CacheUpdateRunner>(nextRunnable.myAction));
}
finally {
if (nextRunnable == null) {
updateFinished();
}
}
}
});
// try to obtain the next action or terminate if no actions left
while (!myProject.isDisposed()) {
try {
Ref<CacheUpdateRunner> ref = actionQueue.poll(500, TimeUnit.MILLISECONDS);
if (ref != null) {
return ref.get();
}
}
catch (InterruptedException e) {
LOG.info(e);
}
}
IndexUpdateRunnable nextUpdateRunnable = null;
return null;
}
@Nullable
private IndexUpdateRunnable getNextUpdateFromQueue() {
try {
nextUpdateRunnable = myUpdatesQueue.isEmpty()? null : myUpdatesQueue.pullFirst();
if (nextUpdateRunnable == null) {
// really terminate the task
myActionQueue.offer(NULL_ACTION);
}
else {
//run next dumb action
// run next action under already existing progress indicator
myActionQueue.offer(new Ref<CacheUpdateRunner>(nextUpdateRunnable.myAction));
}
return myUpdatesQueue.isEmpty()? null : myUpdatesQueue.pullFirst();
}
catch (Throwable e) {
myActionQueue.offer(NULL_ACTION);
LOG.info(e);
}
finally {
if (nextUpdateRunnable == null) {
updateFinished();
}
return null;
}
}
});