Automatically rebuild out-of-date NoteDb drafts
Uses the same mechanism as when rebuilding changes, except checking the state of the relevant drafts ref in All-Users. The one place we couldn't do this easily is in PatchLineCommentsUtil#draftsByAuthor, since it doesn't have a Change object available for each change, and we don't want to go overboard in reading the notes. Just bail and skip rebuilding in that particular case, marking it as deprecated so it doesn't pick up any new users. Change-Id: Iaeccc9e665eb6ee2ffa4583f5add8d0ba9968d70
This commit is contained in:
@@ -24,14 +24,18 @@ import com.google.gerrit.reviewdb.client.PatchLineComment;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.client.RefNames;
|
||||
import com.google.gerrit.reviewdb.client.RevId;
|
||||
import com.google.gerrit.server.project.NoSuchChangeException;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.assistedinject.AssistedInject;
|
||||
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.ObjectReader;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.notes.NoteMap;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -41,20 +45,34 @@ import java.io.IOException;
|
||||
*/
|
||||
public class DraftCommentNotes extends AbstractChangeNotes<DraftCommentNotes> {
|
||||
public interface Factory {
|
||||
DraftCommentNotes create(Change.Id changeId, Account.Id accountId);
|
||||
DraftCommentNotes create(Change change, Account.Id accountId);
|
||||
DraftCommentNotes createWithAutoRebuildingDisabled(
|
||||
Change.Id changeId, Account.Id accountId);
|
||||
}
|
||||
|
||||
private final Change change;
|
||||
private final Account.Id author;
|
||||
|
||||
private ImmutableListMultimap<RevId, PatchLineComment> comments;
|
||||
private RevisionNoteMap revisionNoteMap;
|
||||
|
||||
@AssistedInject
|
||||
DraftCommentNotes(
|
||||
Args args,
|
||||
@Assisted Change change,
|
||||
@Assisted Account.Id author) {
|
||||
super(args, change.getId());
|
||||
this.change = change;
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
@AssistedInject
|
||||
DraftCommentNotes(
|
||||
Args args,
|
||||
@Assisted Change.Id changeId,
|
||||
@Assisted Account.Id author) {
|
||||
super(args, changeId);
|
||||
this.change = null;
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
@@ -118,6 +136,36 @@ public class DraftCommentNotes extends AbstractChangeNotes<DraftCommentNotes> {
|
||||
return args.allUsers;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LoadHandle openHandle(Repository repo) throws IOException {
|
||||
if (change != null) {
|
||||
NoteDbChangeState state = NoteDbChangeState.parse(change);
|
||||
// Only check if this particular user's drafts are up to date, to avoid
|
||||
// reading unnecessary refs.
|
||||
if (state == null || !state.areDraftsUpToDate(repo, author)) {
|
||||
return rebuildAndOpen(repo);
|
||||
}
|
||||
}
|
||||
return super.openHandle(repo);
|
||||
}
|
||||
|
||||
private LoadHandle rebuildAndOpen(Repository repo) throws IOException {
|
||||
try {
|
||||
NoteDbChangeState newState =
|
||||
args.rebuilder.get().rebuild(args.db.get(), getChangeId());
|
||||
if (newState == null) {
|
||||
return super.openHandle(repo); // May be null in tests.
|
||||
}
|
||||
ObjectId draftsId = newState.getDraftIds().get(author);
|
||||
repo.scanForRepoChanges();
|
||||
return LoadHandle.create(new RevWalk(repo), draftsId);
|
||||
} catch (NoSuchChangeException e) {
|
||||
return super.openHandle(repo);
|
||||
} catch (OrmException | ConfigInvalidException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
NoteMap getNoteMap() {
|
||||
return revisionNoteMap != null ? revisionNoteMap.noteMap : null;
|
||||
|
Reference in New Issue
Block a user