[vcs-log] dispose single task controller

Cancel current task and remove all requests.
This commit is contained in:
Julia Beliaeva
2017-11-27 18:47:57 +03:00
parent bdc586c290
commit 780a40da0c
5 changed files with 46 additions and 13 deletions
@@ -15,6 +15,7 @@
*/
package com.intellij.vcs.log.data;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.util.Consumer;
@@ -36,7 +37,7 @@ import java.util.List;
* <p/>
* The class is thread-safe: all operations are synchronized.
*/
public abstract class SingleTaskController<Request, Result> {
public abstract class SingleTaskController<Request, Result> implements Disposable {
private static final Logger LOG = Logger.getInstance(SingleTaskController.class);
@@ -47,6 +48,8 @@ public abstract class SingleTaskController<Request, Result> {
@NotNull private List<Request> myAwaitingRequests;
@Nullable private ProgressIndicator myRunningTask;
private boolean myIsDisposed = false;
public SingleTaskController(@NotNull Consumer<Result> handler, boolean cancelRunning) {
myResultHandler = handler;
myAwaitingRequests = ContainerUtil.newLinkedList();
@@ -60,6 +63,7 @@ public abstract class SingleTaskController<Request, Result> {
*/
public final void request(@NotNull Request requests) {
synchronized (LOCK) {
if (myIsDisposed) return;
myAwaitingRequests.add(requests);
LOG.debug("Added requests: " + requests);
if (myRunningTask != null && myCancelRunning) {
@@ -148,4 +152,19 @@ public abstract class SingleTaskController<Request, Result> {
}
}
}
@Override
public void dispose() {
synchronized (LOCK) {
if (myIsDisposed) return;
myIsDisposed = true;
if (myRunningTask != null) {
myRunningTask.cancel();
myRunningTask = null;
}
myAwaitingRequests.clear();
}
}
}
@@ -124,6 +124,7 @@ public class VcsLogData implements Disposable, VcsLogDataProvider {
myRefresher = new VcsLogRefresherImpl(myProject, myStorage, myLogProviders, myUserRegistry, myIndex, progress, myTopCommitsDetailsCache,
this::fireDataPackChangeEvent, FAILING_EXCEPTION_HANDLER, RECENT_COMMITS_COUNT);
Disposer.register(this, myRefresher);
myContainingBranchesGetter = new ContainingBranchesGetter(this, this);
@@ -15,11 +15,13 @@
*/
package com.intellij.vcs.log.data;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
@@ -39,7 +41,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.stream.Collectors;
public class VcsLogRefresherImpl implements VcsLogRefresher {
public class VcsLogRefresherImpl implements VcsLogRefresher, Disposable {
private static final Logger LOG = Logger.getInstance(VcsLogRefresherImpl.class);
@@ -88,6 +90,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
return VcsLogRefresherImpl.this.startNewBackgroundTask(new MyRefreshTask(myDataPack));
}
};
Disposer.register(this, mySingleTaskController);
}
protected ProgressIndicator startNewBackgroundTask(@NotNull final Task.Backgroundable refreshTask) {
@@ -192,6 +195,10 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
return myProgress;
}
@Override
public void dispose() {
}
private class MyRefreshTask extends Task.Backgroundable {
@NotNull private DataPack myCurrentDataPack;
@@ -131,6 +131,7 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable {
myIndexingLimit.put(root, new AtomicInteger(getIndexingLimit()));
}
Disposer.register(myIndexStorage != null ? myIndexStorage : this, mySingleTaskController);
Disposer.register(disposableParent, this);
}
@@ -449,7 +450,7 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable {
public void dispose() {
}
static class IndexStorage {
static class IndexStorage implements Disposable {
private static final String COMMITS = "commits";
private static final String MESSAGES = "messages";
private static final String PARENTS = "parents";
@@ -471,8 +472,7 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable {
@NotNull FatalErrorHandler fatalErrorHandler,
@NotNull Disposable parentDisposable)
throws IOException {
Disposable disposable = Disposer.newDisposable();
Disposer.register(parentDisposable, disposable);
Disposer.register(parentDisposable, this);
try {
int version = getVersion();
@@ -480,28 +480,28 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable {
File commitsStorage = getStorageFile(INDEX, COMMITS, logId, version);
myIsFresh = !commitsStorage.exists();
commits = new PersistentSetImpl<>(commitsStorage, EnumeratorIntegerDescriptor.INSTANCE, Page.PAGE_SIZE, null, version);
Disposer.register(disposable, () -> catchAndWarn(commits::close));
Disposer.register(this, () -> catchAndWarn(commits::close));
File messagesStorage = getStorageFile(INDEX, MESSAGES, logId, VcsLogStorageImpl.VERSION + MESSAGES_VERSION);
messages = new PersistentHashMap<>(messagesStorage, new IntInlineKeyDescriptor(), EnumeratorStringDescriptor.INSTANCE,
Page.PAGE_SIZE);
Disposer.register(disposable, () -> catchAndWarn(messages::close));
Disposer.register(this, () -> catchAndWarn(messages::close));
trigrams = new VcsLogMessagesTrigramIndex(logId, fatalErrorHandler, disposable);
users = new VcsLogUserIndex(logId, userRegistry, fatalErrorHandler, disposable);
paths = new VcsLogPathsIndex(logId, roots, fatalErrorHandler, disposable);
trigrams = new VcsLogMessagesTrigramIndex(logId, fatalErrorHandler, this);
users = new VcsLogUserIndex(logId, userRegistry, fatalErrorHandler, this);
paths = new VcsLogPathsIndex(logId, roots, fatalErrorHandler, this);
File parentsStorage = getStorageFile(INDEX, PARENTS, logId, version);
parents = new PersistentHashMap<>(parentsStorage, EnumeratorIntegerDescriptor.INSTANCE,
new IntListDataExternalizer(), Page.PAGE_SIZE, version);
Disposer.register(disposable, () -> catchAndWarn(parents::close));
Disposer.register(this, () -> catchAndWarn(parents::close));
File renamesStorage = getStorageFile(INDEX, RENAMES, logId, version);
renames = new PersistentSetImpl<>(renamesStorage, EnumeratorIntegerDescriptor.INSTANCE, Page.PAGE_SIZE, null, version);
Disposer.register(disposable, () -> catchAndWarn(renames::close));
Disposer.register(this, () -> catchAndWarn(renames::close));
}
catch (Throwable t) {
Disposer.dispose(disposable);
Disposer.dispose(this);
throw t;
}
}
@@ -532,6 +532,10 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable {
public boolean isFresh() {
return myIsFresh;
}
@Override
public void dispose() {
}
}
private class MySingleTaskController extends SingleTaskController<IndexingRequest, Void> {
@@ -23,6 +23,7 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
@@ -79,6 +80,7 @@ public class VisiblePackRefresherImpl implements VisiblePackRefresher, Disposabl
return indicator;
}
};
Disposer.register(this, myTaskController);
myIndexingFinishedListener = root -> myTaskController.request(new IndexingFinishedRequest(root));
myLogData.getIndex().addListener(myIndexingFinishedListener);