NoteDb: Auto-rebuild when either reads or writes are enabled
We plan to switch from write-only to read-write in a running server after doing a batch rebuild. For that to work, we need to assume that changes that are being written consistently will stay up-to-date in NoteDb. Previously, auto-rebuilding only happened when reads were enabled; after this change, it will happen when either reads or writes are enabled. Change-Id: I265ef862df84d81e6917400309193e0681dd56db
This commit is contained in:
@@ -97,14 +97,16 @@ public abstract class AbstractChangeNotes<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected final Args args;
|
protected final Args args;
|
||||||
|
protected final boolean autoRebuild;
|
||||||
private final Change.Id changeId;
|
private final Change.Id changeId;
|
||||||
|
|
||||||
private ObjectId revision;
|
private ObjectId revision;
|
||||||
private boolean loaded;
|
private boolean loaded;
|
||||||
|
|
||||||
AbstractChangeNotes(Args args, Change.Id changeId) {
|
AbstractChangeNotes(Args args, Change.Id changeId, boolean autoRebuild) {
|
||||||
this.args = checkNotNull(args);
|
this.args = checkNotNull(args);
|
||||||
this.changeId = checkNotNull(changeId);
|
this.changeId = checkNotNull(changeId);
|
||||||
|
this.autoRebuild = autoRebuild;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Change.Id getChangeId() {
|
public Change.Id getChangeId() {
|
||||||
@@ -120,7 +122,9 @@ public abstract class AbstractChangeNotes<T> {
|
|||||||
if (loaded) {
|
if (loaded) {
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
if (!args.migration.readChanges()) {
|
boolean read = args.migration.readChanges();
|
||||||
|
boolean readOrWrite = read || args.migration.writeChanges();
|
||||||
|
if (!readOrWrite || !autoRebuild) {
|
||||||
loadDefaults();
|
loadDefaults();
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
@@ -129,9 +133,15 @@ public abstract class AbstractChangeNotes<T> {
|
|||||||
}
|
}
|
||||||
try (Timer1.Context timer = args.metrics.readLatency.start(CHANGES);
|
try (Timer1.Context timer = args.metrics.readLatency.start(CHANGES);
|
||||||
Repository repo = args.repoManager.openRepository(getProjectName());
|
Repository repo = args.repoManager.openRepository(getProjectName());
|
||||||
|
// Call openHandle even if reading is disabled, to trigger
|
||||||
|
// auto-rebuilding before this object may get passed to a ChangeUpdate.
|
||||||
LoadHandle handle = openHandle(repo)) {
|
LoadHandle handle = openHandle(repo)) {
|
||||||
revision = handle.id();
|
if (read) {
|
||||||
onLoad(handle);
|
revision = handle.id();
|
||||||
|
onLoad(handle);
|
||||||
|
} else {
|
||||||
|
loadDefaults();
|
||||||
|
}
|
||||||
loaded = true;
|
loaded = true;
|
||||||
} catch (ConfigInvalidException | IOException e) {
|
} catch (ConfigInvalidException | IOException e) {
|
||||||
throw new OrmException(e);
|
throw new OrmException(e);
|
||||||
@@ -145,7 +155,11 @@ public abstract class AbstractChangeNotes<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected LoadHandle openHandle(Repository repo) throws IOException {
|
protected LoadHandle openHandle(Repository repo) throws IOException {
|
||||||
return LoadHandle.create(ChangeNotesCommit.newRevWalk(repo), readRef(repo));
|
return openHandle(repo, readRef(repo));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected LoadHandle openHandle(Repository repo, ObjectId id) {
|
||||||
|
return LoadHandle.create(ChangeNotesCommit.newRevWalk(repo), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public T reload() throws OrmException {
|
public T reload() throws OrmException {
|
||||||
|
@@ -377,7 +377,6 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
|||||||
|
|
||||||
private final Project.NameKey project;
|
private final Project.NameKey project;
|
||||||
private final Change change;
|
private final Change change;
|
||||||
private final boolean autoRebuild;
|
|
||||||
private final RefCache refs;
|
private final RefCache refs;
|
||||||
|
|
||||||
private ImmutableSortedMap<PatchSet.Id, PatchSet> patchSets;
|
private ImmutableSortedMap<PatchSet.Id, PatchSet> patchSets;
|
||||||
@@ -403,10 +402,9 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
|||||||
|
|
||||||
private ChangeNotes(Args args, Project.NameKey project, Change change,
|
private ChangeNotes(Args args, Project.NameKey project, Change change,
|
||||||
boolean autoRebuild, @Nullable RefCache refs) {
|
boolean autoRebuild, @Nullable RefCache refs) {
|
||||||
super(args, change.getId());
|
super(args, change.getId(), autoRebuild);
|
||||||
this.project = project;
|
this.project = project;
|
||||||
this.change = new Change(change);
|
this.change = new Change(change);
|
||||||
this.autoRebuild = autoRebuild;
|
|
||||||
this.refs = refs;
|
this.refs = refs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,26 +624,31 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
|||||||
protected LoadHandle openHandle(Repository repo) throws IOException {
|
protected LoadHandle openHandle(Repository repo) throws IOException {
|
||||||
if (autoRebuild) {
|
if (autoRebuild) {
|
||||||
NoteDbChangeState state = NoteDbChangeState.parse(change);
|
NoteDbChangeState state = NoteDbChangeState.parse(change);
|
||||||
|
ObjectId id = readRef(repo);
|
||||||
|
if (state == null && id == null) {
|
||||||
|
return super.openHandle(repo, id);
|
||||||
|
}
|
||||||
RefCache refs = this.refs != null ? this.refs : new RepoRefCache(repo);
|
RefCache refs = this.refs != null ? this.refs : new RepoRefCache(repo);
|
||||||
if (!NoteDbChangeState.isChangeUpToDate(state, refs, getChangeId())) {
|
if (!NoteDbChangeState.isChangeUpToDate(state, refs, getChangeId())) {
|
||||||
return rebuildAndOpen(repo);
|
return rebuildAndOpen(repo, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return super.openHandle(repo);
|
return super.openHandle(repo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoadHandle rebuildAndOpen(Repository repo) throws IOException {
|
private LoadHandle rebuildAndOpen(Repository repo, ObjectId oldId)
|
||||||
|
throws IOException {
|
||||||
try {
|
try {
|
||||||
NoteDbChangeState newState =
|
NoteDbChangeState newState =
|
||||||
args.rebuilder.get().rebuild(args.db.get(), getChangeId());
|
args.rebuilder.get().rebuild(args.db.get(), getChangeId());
|
||||||
if (newState == null) {
|
if (newState == null) {
|
||||||
return super.openHandle(repo); // May be null in tests.
|
return super.openHandle(repo, oldId); // May be null in tests.
|
||||||
}
|
}
|
||||||
repo.scanForRepoChanges();
|
repo.scanForRepoChanges();
|
||||||
return LoadHandle.create(
|
return LoadHandle.create(
|
||||||
ChangeNotesCommit.newRevWalk(repo), newState.getChangeMetaId());
|
ChangeNotesCommit.newRevWalk(repo), newState.getChangeMetaId());
|
||||||
} catch (NoSuchChangeException e) {
|
} catch (NoSuchChangeException e) {
|
||||||
return super.openHandle(repo);
|
return super.openHandle(repo, oldId);
|
||||||
} catch (OrmException | ConfigInvalidException e) {
|
} catch (OrmException | ConfigInvalidException e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
|
@@ -52,7 +52,6 @@ public class DraftCommentNotes extends AbstractChangeNotes<DraftCommentNotes> {
|
|||||||
|
|
||||||
private final Change change;
|
private final Change change;
|
||||||
private final Account.Id author;
|
private final Account.Id author;
|
||||||
private final boolean autoRebuild;
|
|
||||||
|
|
||||||
private ImmutableListMultimap<RevId, PatchLineComment> comments;
|
private ImmutableListMultimap<RevId, PatchLineComment> comments;
|
||||||
private RevisionNoteMap revisionNoteMap;
|
private RevisionNoteMap revisionNoteMap;
|
||||||
@@ -70,10 +69,9 @@ public class DraftCommentNotes extends AbstractChangeNotes<DraftCommentNotes> {
|
|||||||
Args args,
|
Args args,
|
||||||
@Assisted Change.Id changeId,
|
@Assisted Change.Id changeId,
|
||||||
@Assisted Account.Id author) {
|
@Assisted Account.Id author) {
|
||||||
super(args, changeId);
|
super(args, changeId, true);
|
||||||
this.change = null;
|
this.change = null;
|
||||||
this.author = author;
|
this.author = author;
|
||||||
this.autoRebuild = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DraftCommentNotes(
|
DraftCommentNotes(
|
||||||
@@ -81,10 +79,9 @@ public class DraftCommentNotes extends AbstractChangeNotes<DraftCommentNotes> {
|
|||||||
Change change,
|
Change change,
|
||||||
Account.Id author,
|
Account.Id author,
|
||||||
boolean autoRebuild) {
|
boolean autoRebuild) {
|
||||||
super(args, change.getId());
|
super(args, change.getId(), autoRebuild);
|
||||||
this.change = change;
|
this.change = change;
|
||||||
this.author = author;
|
this.author = author;
|
||||||
this.autoRebuild = autoRebuild;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RevisionNoteMap getRevisionNoteMap() {
|
RevisionNoteMap getRevisionNoteMap() {
|
||||||
|
Reference in New Issue
Block a user