Drain executor of index change requests before closing index

When Gerrit needs to exit because of a SIG-HUP, we need to make
sure to drain all pending threads that have outstanding indexing
operations not yet flushed to disk.

This does not have to be confused with the index close which may
happen during on-line reindexing and needs to preserve the current
indexing executor.

This is a rework of I6ec90eb73 and I7bda13058 with an alternative
approach that keeps both index consistency across restarts and on-line
reindexing.

Bug: Issue 5200
Bug: Issue 4618
Change-Id: Id332ec0215de4777fabef6ca310c510ba90c9760
This commit is contained in:
Luca Milanesio
2016-12-30 15:02:57 +00:00
parent e7fc0eb55f
commit df10d85174
7 changed files with 33 additions and 16 deletions

View File

@@ -97,4 +97,8 @@ public class ChangeSubIndex extends AbstractLuceneIndex<Change.Id, ChangeData>
}
super.add(doc, values);
}
@Override
public void stop() {
}
}

View File

@@ -214,4 +214,8 @@ public class LuceneAccountIndex
// to reindex when those change.
return accountCache.get(id);
}
@Override
public void stop() {
}
}

View File

@@ -30,12 +30,11 @@ import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
@@ -96,6 +95,7 @@ import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
* Secondary index implementation using Apache Lucene.
@@ -186,22 +186,19 @@ public class LuceneChangeIndex implements ChangeIndex {
}
}
@Override
public void stop() {
MoreExecutors.shutdownAndAwaitTermination(
executor, Long.MAX_VALUE, TimeUnit.SECONDS);
}
@Override
public void close() {
List<ListenableFuture<?>> closeFutures = Lists.newArrayListWithCapacity(2);
closeFutures.add(executor.submit(new Runnable() {
@Override
public void run() {
openIndex.close();
}
}));
closeFutures.add(executor.submit(new Runnable() {
@Override
public void run() {
closedIndex.close();
}
}));
Futures.getUnchecked(Futures.allAsList(closeFutures));
try {
openIndex.close();
} finally {
closedIndex.close();
}
}
@Override

View File

@@ -34,6 +34,9 @@ public interface Index<K, V> {
/** @return the schema version used by this index. */
Schema<V> getSchema();
/** Stop and await termination of all executor threads */
void stop();
/** Close this index. */
void close();

View File

@@ -98,6 +98,7 @@ public abstract class IndexCollection<K, V, I extends Index<K, V>>
}
for (I write : writeIndexes) {
if (write != read) {
write.stop();
write.close();
}
}

View File

@@ -57,4 +57,8 @@ public class DummyChangeIndex implements ChangeIndex {
public int getMaxLimit() {
return Integer.MAX_VALUE;
}
@Override
public void stop() {
}
}

View File

@@ -108,4 +108,8 @@ public class FakeChangeIndex implements ChangeIndex {
public void markReady(boolean ready) {
throw new UnsupportedOperationException();
}
@Override
public void stop() {
}
}