cancel previous async editor highlighter update when new one is scheduled

This commit is contained in:
peter
2017-04-25 18:46:57 +02:00
parent b305f2bc3d
commit 9ceecdf8a1
2 changed files with 10 additions and 7 deletions
@@ -32,7 +32,7 @@ import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import java.util.Set;
import java.util.Map;
import java.util.concurrent.*;
/**
@@ -40,7 +40,7 @@ import java.util.concurrent.*;
*/
public class AsyncHighlighterUpdater extends ReadTask {
private static final ExecutorService ourExecutor = AppExecutorUtil.createBoundedApplicationPoolExecutor("AsyncEditorLoader pool", 2);
private static final Set<Future<?>> ourHighlighterFutures = ContainerUtil.newConcurrentSet();
private static final Map<Editor, Future<?>> ourHighlighterFutures = ContainerUtil.newConcurrentMap();
private final Project myProject;
private final Editor myEditor;
private final VirtualFile myFile;
@@ -72,15 +72,18 @@ public class AsyncHighlighterUpdater extends ReadTask {
AsyncHighlighterUpdater task = new AsyncHighlighterUpdater(project, editor, file);
if (task.isEverythingValid()) {
CompletableFuture<?> future = ProgressIndicatorUtils.scheduleWithWriteActionPriority(ourExecutor, task);
ourHighlighterFutures.add(future);
future.whenComplete((a, b) -> ourHighlighterFutures.remove(future));
Future<?> prev = ourHighlighterFutures.put(editor, future);
if (prev != null) {
prev.cancel(false);
}
future.whenComplete((a, b) -> ourHighlighterFutures.remove(editor, future));
}
}
@TestOnly
public static void completeAsyncTasks() {
assert !ApplicationManager.getApplication().isWriteAccessAllowed();
ApplicationManager.getApplication().invokeAndWait(() -> ourHighlighterFutures.forEach(AsyncHighlighterUpdater::waitForFuture));
ApplicationManager.getApplication().invokeAndWait(() -> ourHighlighterFutures.values().forEach(AsyncHighlighterUpdater::waitForFuture));
UIUtil.dispatchAllInvocationEvents();
}
@@ -202,13 +202,13 @@ public class ProgressIndicatorUtils {
if (continuation == null) {
future.complete(null);
}
else {
else if (!future.isCancelled()) {
application.invokeLater(new Runnable() {
@Override
public void run() {
application.removeApplicationListener(listener); // remove listener early to prevent firing it during continuation execution
try {
if (!progressIndicator.isCanceled()) {
if (!progressIndicator.isCanceled() && !future.isCancelled()) {
continuation.getAction().run();
}
}