IDEA-140501 Send repo update events on a separate thread

Otherwise, if update() is called from
VcsRepositoryManager#getRepositoryForRoot (a Repository for the root
was not created yet => it is being created at once) other
messages from the message bus queue block the current thread from
returning the created GitRepositoryImpl instance, and moreover may
cause other GitRepositoryImpl() creations (because the repo map is
still not up-to-date).

A correct solution is to disable all git/hg actions while the repo map
is being updated, but it is a large change. On the other hand, sending
notification events on a separate thread shouldn't hurt.
This commit is contained in:
Kirill Likhodedov
2015-05-21 19:04:14 +03:00
parent 85fcb6d85c
commit a88ad70110
2 changed files with 20 additions and 6 deletions
@@ -17,6 +17,7 @@ package git4idea.repo;
import com.intellij.dvcs.repo.RepositoryImpl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vcs.AbstractVcs;
@@ -206,12 +207,19 @@ public class GitRepositoryImpl extends RepositoryImpl implements GitRepository {
}
// previous info can be null before the first update
private static void notifyListeners(@NotNull GitRepository repository, @Nullable GitRepoInfo previousInfo, @NotNull GitRepoInfo info) {
private static void notifyListeners(@NotNull final GitRepository repository, @Nullable GitRepoInfo previousInfo, @NotNull GitRepoInfo info) {
if (Disposer.isDisposed(repository.getProject())) {
return;
}
if (!info.equals(previousInfo)) {
repository.getProject().getMessageBus().syncPublisher(GIT_REPO_CHANGE).repositoryChanged(repository);
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
public void run() {
Project project = repository.getProject();
if (!project.isDisposed()) {
project.getMessageBus().syncPublisher(GIT_REPO_CHANGE).repositoryChanged(repository);
}
}
});
}
}
@@ -18,6 +18,7 @@ package org.zmlx.hg4idea.repo;
import com.intellij.dvcs.repo.RepositoryImpl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
@@ -213,7 +214,7 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository {
HgRepoInfo currentInfo = readRepoInfo();
// update only if something changed!!! if update every time - new log will be refreshed every time, too.
// Then blinking and do not work properly;
Project project = getProject();
final Project project = getProject();
if (!project.isDisposed() && !currentInfo.equals(myInfo)) {
myInfo = currentInfo;
HgCommandResult branchCommandResult = new HgBranchesCommand(project, getRoot()).collectBranches();
@@ -224,9 +225,14 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository {
else {
myOpenedBranches = HgBranchesCommand.collectNames(branchCommandResult);
}
if (!project.isDisposed()) {
project.getMessageBus().syncPublisher(HgVcs.STATUS_TOPIC).update(project, getRoot());
}
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
public void run() {
if (!project.isDisposed()) {
project.getMessageBus().syncPublisher(HgVcs.STATUS_TOPIC).update(project, getRoot());
}
}
});
}
}