[vcs-log] index out of heavy process, cancel indexing on heavy process starting

This commit is contained in:
Julia Beliaeva
2017-07-26 00:38:00 +03:00
parent be1f8a965d
commit 1c206fcf6e
2 changed files with 46 additions and 4 deletions
@@ -19,7 +19,10 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.*;
import com.intellij.openapi.progress.PerformInBackgroundOption;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
@@ -36,6 +39,7 @@ import com.intellij.util.io.*;
import com.intellij.vcs.log.*;
import com.intellij.vcs.log.data.*;
import com.intellij.vcs.log.impl.FatalErrorHandler;
import com.intellij.vcs.log.impl.HeavyAwareExecutor;
import com.intellij.vcs.log.ui.filter.VcsLogTextFilterImpl;
import com.intellij.vcs.log.util.PersistentSet;
import com.intellij.vcs.log.util.PersistentSetImpl;
@@ -491,6 +495,7 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable {
ApplicationManager.getApplication().invokeLater(() -> {
Task.Backgroundable task = new Task.Backgroundable(VcsLogPersistentIndex.this.myProject, "Indexing Commit Data", true,
PerformInBackgroundOption.ALWAYS_BACKGROUND) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
IndexingRequest request;
@@ -510,7 +515,7 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable {
taskCompleted(null);
}
};
ProgressManager.getInstance().runProcessWithProgressAsynchronously(task, indicator);
HeavyAwareExecutor.executeOutOfHeavyProcess(task, indicator);
});
return indicator;
}
@@ -16,13 +16,19 @@
package com.intellij.vcs.log.impl;
import com.intellij.concurrency.JobScheduler;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.progress.impl.CoreProgressManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.io.storage.HeavyProcessLatch;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.TimeUnit;
class HeavyAwareExecutor {
static void executeOutOfHeavyProcessLater(@NotNull Runnable command, int delayMs) {
public class HeavyAwareExecutor {
public static void executeOutOfHeavyProcessLater(@NotNull Runnable command, int delayMs) {
HeavyProcessLatch.INSTANCE.executeOutOfHeavyProcess(() -> JobScheduler.getScheduler().schedule(() -> {
if (HeavyProcessLatch.INSTANCE.isRunning()) {
executeOutOfHeavyProcessLater(command, delayMs);
@@ -32,4 +38,35 @@ class HeavyAwareExecutor {
}
}, delayMs, TimeUnit.MILLISECONDS));
}
public static void executeOutOfHeavyProcess(@NotNull Task.Backgroundable task, @NotNull ProgressIndicator indicator) {
HeavyProcessLatch.INSTANCE.executeOutOfHeavyProcess(() -> {
if (HeavyProcessLatch.INSTANCE.isRunning()) {
executeOutOfHeavyProcess(task, indicator);
}
else {
Disposable disposable = Disposer.newDisposable();
((CoreProgressManager)ProgressManager.getInstance()).runProcessWithProgressAsynchronously(task, indicator,
() -> Disposer.dispose(disposable));
HeavyProcessLatch.INSTANCE.addListener(new CancellingOnHeavyProcessListener(indicator), disposable);
}
});
}
private static class CancellingOnHeavyProcessListener implements HeavyProcessLatch.HeavyProcessListener {
@NotNull private final ProgressIndicator myIndicator;
public CancellingOnHeavyProcessListener(@NotNull ProgressIndicator indicator) {
myIndicator = indicator;
}
@Override
public void processStarted() {
myIndicator.cancel();
}
@Override
public void processFinished() {
}
}
}