ChangeRebuilderImpl: Don't always drop updates when losing race

Inside the AtomicUpdate where we check if the NoteDbChangeState has
changed, an unequal state comparison does not necessarily mean that
another thread has made the *same* update as this thread is trying to
make. It might have been the same, which is ok to drop, but it might
also be different. In the latter case, we were dropping the change
without even attempting to execute the NoteDbUpdateManager, and
returning to the caller as if the update was successful. The caller
would then fail with a MissingObjectException because the object in
question was never flushed.

Distinguish these two cases with two different OrmRuntimeException.
The latter case gets rethrown as an OrmException to indicate to the
caller that they should build an in-memory RevWalk off of the staged
results instead of trying to read from the repo.

Change-Id: I0510db01d2ef48b5cfa06898392a6c9e4b2136bb
This commit is contained in:
Dave Borowitz
2016-07-22 16:24:17 -04:00
parent 9448ed4c81
commit 51e45017af
3 changed files with 29 additions and 4 deletions

View File

@@ -206,7 +206,8 @@ public class DraftCommentNotes extends AbstractChangeNotes<DraftCommentNotes> {
repo.scanForRepoChanges();
} catch (OrmException | IOException e) {
// See ChangeNotes#rebuildAndOpen.
log.debug("Rebuilding change {} via drafts failed", getChangeId());
log.debug("Rebuilding change {} via drafts failed: {}",
getChangeId(), e.getMessage());
args.metrics.autoRebuildFailureCount.increment(CHANGES);
checkNotNull(r.staged());
return LoadHandle.create(