Check for existence of change's target SHA1 for reindexing When the target branch of a change was advancing rapidly, the reindexing retries applied by the ForwardedIndexingHandlerWithRetries were continuing potentially forever as they were waiting to see the target branch's expected SHA1 for the event. Whilst it is vital to wait for a target branch SHA1 to appear before reindexing a change on a remote site, it isn't essential to have that SHA1 being *exactly* the tip of the target branch, as that moment can be easily missed. Example: - Create two changes C1 and C2 in parallel and push them with %submit option - The changes C1 and C2 will trigger the rapid advance of their target SHA1 - The other nodes may reindex C1 but not C2 because the target branch has advanced more than expected Checking simply the existence of the target SHA1 in the repository is enough to satisfy the conditions for the change being reindexed. Bug: Issue 335353379 Change-Id: Ife361ec3378a60c0d1eb15df0f9570d569adc07a (cherry picked from commit 89d497605c85b3422f2b6958cca1df3fc2dd532f)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java index 063d7bf..54dcca6 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java +++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java
@@ -26,7 +26,6 @@ import com.googlesource.gerrit.plugins.multisite.forwarder.events.ChangeIndexEvent; import java.io.IOException; import java.sql.Timestamp; -import java.util.Objects; import java.util.Optional; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.ObjectId; @@ -102,8 +101,7 @@ .map( e -> (computedChangeTs.get() > e.eventCreatedOn) - || ((computedChangeTs.get() == e.eventCreatedOn) - && (Objects.equals(getBranchTargetSha(), e.targetSha)))) + || ((computedChangeTs.get() == e.eventCreatedOn) && repositoryHas(e.targetSha))) .orElse(true); } @@ -142,6 +140,15 @@ } } + private boolean repositoryHas(String targetSha) { + try (Repository repo = gitRepoMgr.openRepository(changeNotes.get().getProjectName())) { + return repo.parseCommit(ObjectId.fromString(targetSha)) != null; + } catch (IOException e) { + log.warn("Unable to find SHA1 {} for change {}", targetSha, changeId, e); + return false; + } + } + @Override public boolean isChangeConsistent() { Optional<ChangeNotes> notes = getChangeNotes();