Only recheck mergeable on reindex with a flag
The mergeability computation is expensive and should be redundant
after it's been run once. Protect this behavior with a flag that
defaults to false, and instruct users to run reindex with the flag in
the release notes.
Change-Id: I3c6140b9a727165b8b43712a0d162c530db048a6
diff --git a/ReleaseNotes/ReleaseNotes-2.9.txt b/ReleaseNotes/ReleaseNotes-2.9.txt
index c0e2fcb..fc764a4 100644
--- a/ReleaseNotes/ReleaseNotes-2.9.txt
+++ b/ReleaseNotes/ReleaseNotes-2.9.txt
@@ -19,6 +19,7 @@
*WARNING:* This release contains schema changes. To upgrade:
----
java -jar gerrit.war init -d site_path
+ java -jar gerrit.war reindex --recheck-mergeability -d site_path
----
*WARNING:* Upgrading to 2.9.x requires the server be first upgraded to 2.1.7 (or
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Reindex.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Reindex.java
index 723f08d..ecb5371 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Reindex.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Reindex.java
@@ -47,6 +47,7 @@
import com.google.gerrit.server.cache.CacheRemovalListener;
import com.google.gerrit.server.cache.h2.DefaultCacheFactory;
import com.google.gerrit.server.change.ChangeKindCache;
+import com.google.gerrit.server.change.MergeabilityChecker;
import com.google.gerrit.server.change.MergeabilityChecksExecutor;
import com.google.gerrit.server.change.PatchSetInserter;
import com.google.gerrit.server.config.CanonicalWebUrl;
@@ -116,6 +117,9 @@
@Option(name = "--output", usage = "Prefix for output; path for local disk index, or prefix for remote index")
private String outputBase;
+ @Option(name = "--recheck-mergeable", usage = "Recheck mergeable flag on all changes")
+ private boolean recheckMergeable;
+
@Option(name = "--verbose", usage = "Output debug information for each change")
private boolean verbose;
@@ -195,58 +199,12 @@
install(new DefaultCacheFactory.Module());
factory(ChangeData.Factory.class);
- factory(ProjectState.Factory.class);
- bind(new TypeLiteral<List<CommentLinkInfo>>() {})
- .toProvider(CommentLinkProvider.class).in(SINGLETON);
- bind(IdentifiedUser.class).toProvider(Providers.<IdentifiedUser>of(null));
- bind(CurrentUser.class).to(IdentifiedUser.class);
- bind(String.class).annotatedWith(CanonicalWebUrl.class)
- .toProvider(CanonicalWebUrlProvider.class);
-
- factory(IncludingGroupMembership.Factory.class);
- bind(GroupBackend.class).to(UniversalGroupBackend.class).in(SINGLETON);
- DynamicSet.setOf(binder(), GroupBackend.class);
- bind(InternalGroupBackend.class).in(SINGLETON);
- DynamicSet.bind(binder(), GroupBackend.class).to(SystemGroupBackend.class);
- DynamicSet.bind(binder(), GroupBackend.class).to(InternalGroupBackend.class);
- factory(InternalUser.Factory.class);
-
- factory(PatchSetInserter.Factory.class);
- bind(ChangeHooks.class).to(DisabledChangeHooks.class);
- bind(ReplacePatchSetSender.Factory.class).toProvider(
- Providers.<ReplacePatchSetSender.Factory>of(null));
-
- factory(CapabilityControl.Factory.class);
- factory(MergeUtil.Factory.class);
- DynamicSet.setOf(binder(), GitReferenceUpdatedListener.class);
- DynamicSet.setOf(binder(), CommitValidationListener.class);
- factory(CommitValidators.Factory.class);
- }
- });
-
- modules.add(AccountCacheImpl.module());
- modules.add(AccountByEmailCacheImpl.module());
- modules.add(ChangeKindCache.module());
- modules.add(GroupCacheImpl.module());
- modules.add(GroupIncludeCacheImpl.module());
- modules.add(ProjectCacheImpl.module());
- modules.add(SectionSortCache.module());
-
- modules.add(new AccessControlModule());
- modules.add(new GitModule());
- modules.add(new NoteDbModule());
- modules.add(new PrologModule());
- modules.add(new AbstractModule() {
- @Override
- protected void configure() {
- }
-
- @Provides
- @Singleton
- @MergeabilityChecksExecutor
- public WorkQueue.Executor createMergeabilityChecksExecutor(
- WorkQueue queues) {
- return queues.createQueue(1, "MergeabilityChecks");
+ if (recheckMergeable) {
+ install(new MergeabilityModule());
+ } else {
+ bind(MergeabilityChecker.class)
+ .toProvider(Providers.<MergeabilityChecker> of(null));
+ }
}
});
@@ -294,6 +252,59 @@
}
}
+ private static class MergeabilityModule extends FactoryModule {
+ @Override
+ public void configure() {
+ factory(ProjectState.Factory.class);
+ bind(new TypeLiteral<List<CommentLinkInfo>>() {})
+ .toProvider(CommentLinkProvider.class).in(SINGLETON);
+ bind(IdentifiedUser.class).toProvider(Providers.<IdentifiedUser>of(null));
+ bind(CurrentUser.class).to(IdentifiedUser.class);
+ bind(String.class).annotatedWith(CanonicalWebUrl.class)
+ .toProvider(CanonicalWebUrlProvider.class);
+
+ factory(IncludingGroupMembership.Factory.class);
+ bind(GroupBackend.class).to(UniversalGroupBackend.class).in(SINGLETON);
+ DynamicSet.setOf(binder(), GroupBackend.class);
+ bind(InternalGroupBackend.class).in(SINGLETON);
+ DynamicSet.bind(binder(), GroupBackend.class).to(SystemGroupBackend.class);
+ DynamicSet.bind(binder(), GroupBackend.class).to(InternalGroupBackend.class);
+ factory(InternalUser.Factory.class);
+
+ factory(PatchSetInserter.Factory.class);
+ bind(ChangeHooks.class).to(DisabledChangeHooks.class);
+ bind(ReplacePatchSetSender.Factory.class).toProvider(
+ Providers.<ReplacePatchSetSender.Factory>of(null));
+
+ factory(CapabilityControl.Factory.class);
+ factory(MergeUtil.Factory.class);
+ DynamicSet.setOf(binder(), GitReferenceUpdatedListener.class);
+ DynamicSet.setOf(binder(), CommitValidationListener.class);
+ factory(CommitValidators.Factory.class);
+
+ install(AccountCacheImpl.module());
+ install(AccountByEmailCacheImpl.module());
+ install(ChangeKindCache.module());
+ install(GroupCacheImpl.module());
+ install(GroupIncludeCacheImpl.module());
+ install(ProjectCacheImpl.module());
+ install(SectionSortCache.module());
+
+ install(new AccessControlModule());
+ install(new GitModule());
+ install(new NoteDbModule());
+ install(new PrologModule());
+ }
+
+ @Provides
+ @Singleton
+ @MergeabilityChecksExecutor
+ public WorkQueue.Executor createMergeabilityChecksExecutor(
+ WorkQueue queues) {
+ return queues.createQueue(1, "MergeabilityChecks");
+ }
+ }
+
private int indexAll() throws Exception {
ReviewDb db = sysInjector.getInstance(ReviewDb.class);
ProgressMonitor pm = new TextProgressMonitor();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeBatchIndexer.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeBatchIndexer.java
index 0334715..a1075fa 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeBatchIndexer.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeBatchIndexer.java
@@ -27,6 +27,7 @@
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.common.Nullable;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
@@ -118,7 +119,7 @@
GitRepositoryManager repoManager,
@IndexExecutor ListeningExecutorService executor,
ChangeIndexer.Factory indexerFactory,
- MergeabilityChecker mergeabilityChecker) {
+ @Nullable MergeabilityChecker mergeabilityChecker) {
this.schemaFactory = schemaFactory;
this.changeDataFactory = changeDataFactory;
this.repoManager = repoManager;
@@ -149,10 +150,7 @@
final AtomicBoolean ok = new AtomicBoolean(true);
for (final Project.NameKey project : projects) {
- try {
- mergeabilityChecker.update(project);
- } catch (IOException e) {
- log.error("Error in mergeability checker", e);
+ if (!updateMergeable(project)) {
ok.set(false);
}
final ListenableFuture<?> future = executor.submit(reindexProject(
@@ -210,6 +208,18 @@
return new Result(sw, ok.get(), doneTask.getCount(), failedTask.getCount());
}
+ private boolean updateMergeable(Project.NameKey project) {
+ if (mergeabilityChecker != null) {
+ try {
+ mergeabilityChecker.update(project);
+ } catch (IOException e) {
+ log.error("Error in mergeability checker", e);
+ return false;
+ }
+ }
+ return true;
+ }
+
private Callable<Void> reindexProject(final ChangeIndexer indexer,
final Project.NameKey project, final Task done, final Task failed,
final PrintWriter verboseWriter) {