From fc29d9c650bb6fb93bad989ecd7c36bef5df65ac Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Fri, 12 Sep 2014 16:52:09 +0400 Subject: [PATCH] Priority executor service added for loading commits. * SingleThreadExecutor used; * store appropriate future instead of indicator; * cancel loading via future.cancel --- .../intellij/dvcs/push/PushController.java | 87 +++++++++---------- .../dvcs/push/ui/EditableTreeNode.java | 8 +- .../intellij/dvcs/push/ui/RepositoryNode.java | 16 ++-- 3 files changed, 53 insertions(+), 58 deletions(-) diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java index d1459190d3b9..cd0cc7a1ef7a 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java @@ -20,11 +20,9 @@ import com.intellij.dvcs.push.ui.*; import com.intellij.dvcs.repo.Repository; import com.intellij.dvcs.repo.RepositoryManager; import com.intellij.openapi.Disposable; -import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; -import com.intellij.openapi.progress.impl.ProgressManagerImpl; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.ValidationInfo; @@ -36,6 +34,7 @@ import com.intellij.ui.CheckedTreeNode; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.hash.HashMap; +import com.intellij.util.ui.UIUtil; import com.intellij.vcs.log.VcsFullCommitDetails; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -45,6 +44,8 @@ import javax.swing.tree.DefaultMutableTreeNode; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicReference; public class PushController implements Disposable { @@ -56,6 +57,7 @@ public class PushController implements Disposable { private boolean mySingleRepoProject; private static final int DEFAULT_CHILDREN_PRESENTATION_NUMBER = 20; private final Map myAdditionalValuesMap; + private final ExecutorService myExecutorService = Executors.newSingleThreadExecutor(); private final Map myView2Model = new TreeMap(); //todo need to sort repositories in ui tree using natural order @@ -207,56 +209,49 @@ public class PushController implements Disposable { final T target = model.getTarget(); if (target == null) return; //todo should be removed when commit loader executor will be modified myPushLog.startLoading(node); - final ProgressIndicator indicator = node.startLoading(); final PushSupport support = model.getSupport(); final AtomicReference result = new AtomicReference(); - Task.Backgroundable task = new Task.Backgroundable(myProject, "Loading Commits", true) { - + Runnable task = new Runnable() { @Override - public void onCancel() { - node.stopLoading(); - } - - @Override - public void onSuccess() { - OutgoingResult outgoing = result.get(); - List errors = outgoing.getErrors(); - if (!errors.isEmpty()) { - myPushLog.setChildren(node, ContainerUtil.map(errors, new Function() { - @Override - public DefaultMutableTreeNode fun(final VcsError error) { - VcsLinkedText errorLinkText = new VcsLinkedText(error.getText(), new VcsLinkListener() { - @Override - public void hyperlinkActivated(@NotNull DefaultMutableTreeNode sourceNode) { - error.handleError(new CommitLoader() { - @Override - public void reloadCommits() { - loadCommits(model, node, false); - } - }); - } - }); - return new TextWithLinkNode(errorLinkText); - } - }), model.isSelected()); - } - else { - model.setLoadedCommits(outgoing.getCommits()); - myPushLog.setChildren(node, - getPresentationForCommits(PushController.this.myProject, model.getLoadedCommits(), - model.getNumberOfShownCommits()), model.isSelected()); - } - } - - @Override - public void run(@NotNull ProgressIndicator indicator) { + public void run() { OutgoingResult outgoing = support.getOutgoingCommitsProvider() .getOutgoingCommits(model.getRepository(), new PushSpec(model.getSource(), model.getTarget()), initial); result.compareAndSet(null, outgoing); + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + OutgoingResult outgoing = result.get(); + List errors = outgoing.getErrors(); + if (!errors.isEmpty()) { + myPushLog.setChildren(node, ContainerUtil.map(errors, new Function() { + @Override + public DefaultMutableTreeNode fun(final VcsError error) { + VcsLinkedText errorLinkText = new VcsLinkedText(error.getText(), new VcsLinkListener() { + @Override + public void hyperlinkActivated(@NotNull DefaultMutableTreeNode sourceNode) { + error.handleError(new CommitLoader() { + @Override + public void reloadCommits() { + loadCommits(model, node, false); + } + }); + } + }); + return new TextWithLinkNode(errorLinkText); + } + }), model.isSelected()); + } + else { + model.setLoadedCommits(outgoing.getCommits()); + myPushLog.setChildren(node, + getPresentationForCommits(PushController.this.myProject, model.getLoadedCommits(), + model.getNumberOfShownCommits()), model.isSelected()); + } + } + }); } }; - - ProgressManagerImpl.runProcessWithProgressAsynchronously(task, indicator, null, ModalityState.any()); + node.startLoading(myExecutorService.submit(task, result)); } public PushLog getPushPanelLog() { @@ -313,9 +308,7 @@ public class PushController implements Disposable { @Override public void dispose() { - for (RepositoryNode node : myView2Model.keySet()) { - node.stopLoading(); - } + myExecutorService.shutdownNow(); } private void addMoreCommits(RepositoryNode repositoryNode) { diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java index 0d291bbb78c8..aab70818082d 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java @@ -15,9 +15,12 @@ */ package com.intellij.dvcs.push.ui; -import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.dvcs.push.OutgoingResult; import org.jetbrains.annotations.NotNull; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicReference; + public interface EditableTreeNode extends CustomRenderedTreeNode { void fireOnChange(); @@ -28,6 +31,5 @@ public interface EditableTreeNode extends CustomRenderedTreeNode { void stopLoading(); - @NotNull - ProgressIndicator startLoading(); + void startLoading(@NotNull Future> future); } diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java index 1ee4e2e9c695..4808064f5c8d 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java @@ -15,9 +15,8 @@ */ package com.intellij.dvcs.push.ui; +import com.intellij.dvcs.push.OutgoingResult; import com.intellij.dvcs.push.PushTargetPanel; -import com.intellij.openapi.progress.EmptyProgressIndicator; -import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.ui.CheckedTreeNode; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.SimpleTextAttributes; @@ -26,10 +25,12 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.border.EmptyBorder; import java.awt.*; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicReference; public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode, Comparable { @NotNull private final RepositoryWithBranchPanel myRepositoryPanel; - private ProgressIndicator myCurrentIndicator; + private Future> myFuture; public RepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel) { super(repositoryPanel); @@ -75,15 +76,14 @@ public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode, @Override public void stopLoading() { - if (myCurrentIndicator != null && myCurrentIndicator.isRunning()) { - myCurrentIndicator.cancel(); + if (myFuture != null && !myFuture.isDone()) { + myFuture.cancel(true); } } @Override - @NotNull - public ProgressIndicator startLoading() { - return myCurrentIndicator = new EmptyProgressIndicator(); + public void startLoading(@NotNull Future> future) { + myFuture = future; } public int compareTo(@NotNull RepositoryNode repositoryNode) {