Automatically rebuild out-of-date NoteDb changes

Changes are always written to ReviewDb before NoteDb, which implies
ReviewDb is the source of truth in case the NoteDb write fails. In
servers running in this mode, we want some way to fix up changes
automatically when we can detect they are out of date. Do this in
ChangeNotes immediately after opening the repo.

This implementation is slightly complicated for several reasons.
First, when auto-rebuilding stale changes, ChangeRebuilder needs to
construct ChangeNotes in order to write out its ChangeUpdates. To
prevent recursive auto-rebuilding, add a new ChangeNotes.Factory
method with an explicit flag to turn it off.

Second, injecting ChangeRebuilder into AbstractChangeNotes.Args
thickens the dependency stack considerably and requires some hacking
to make Guice work out. We need to bind ChangeRebuilder to an
unimplemented version for AbstractChangeNotesTest. And we need to put
a seam[1] in the dependency graph to work around a circular dependency
from ChangeRebuilder back to AbstractChangeNotes.Args.

[1] https://github.com/google/guice/wiki/CyclicDependencies#break-the-cycle-with-a-provider

Change-Id: I1fda0f158d268a28837c93ec10a8ef4877286f08
This commit is contained in:
Dave Borowitz
2016-03-24 09:54:10 -04:00
parent 4b6aa3bff8
commit a30ce68ee1
9 changed files with 203 additions and 40 deletions

View File

@@ -31,6 +31,7 @@ import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RevId;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
@@ -171,6 +172,7 @@ public abstract class AbstractChangeNotesTest extends GerritBaseTests {
bind(StarredChangesUtil.class)
.toProvider(Providers.<StarredChangesUtil> of(null));
bind(MetricMaker.class).to(DisabledMetricMaker.class);
bind(ReviewDb.class).toProvider(Providers.<ReviewDb> of(null));
}
});