Do not retry replication when local repository not found When many repositories get created and deleted in a quick succession it may happen that a repository gets deleted before its replication task starts. Such replication task will keep retrying, possibly indefinitely, but has no chance to succeed. Another scenario where this issue can occur is when a repository gets created but a replica is not reachable for some time. If the repository gets deleted before the replica gets reachable again, the replication task will keep retrying but the local repository will not exist. When handling the RepositoryNotFoundException in PushOne, set the retrying flag to false. This ensures that this replication task is not retried and gets finished. Bug: Issue 15804 Change-Id: Ia55c5ec1c961f4c2aec9ecee8056f22b436e9fda
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java b/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java index ebc8889..693dd73 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
@@ -376,8 +376,12 @@ "Replication to %s completed in %dms, %dms delay, %d retries", uri, elapsed, delay, retryCount); } catch (RepositoryNotFoundException e) { + retryDone(); stateLog.error( - "Cannot replicate " + projectName + "; Local repository error: " + e.getMessage(), + "Cannot replicate " + + projectName + + "; Local repository does not exist: " + + e.getMessage(), getStatesAsArray()); } catch (RemoteRepositoryException e) {
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/PushOneTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/PushOneTest.java index 94f0dc4..4bd084d 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/replication/PushOneTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/replication/PushOneTest.java
@@ -14,6 +14,7 @@ package com.googlesource.gerrit.plugins.replication; +import static com.google.common.truth.Truth.assertThat; import static org.eclipse.jgit.lib.Ref.Storage.NEW; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -46,6 +47,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.eclipse.jgit.errors.NotSupportedException; +import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.ObjectId; @@ -223,6 +225,17 @@ verify(transportMock, never()).push(any(), any()); } + @Test + public void shouldNotKeepRetryingWhenRepositoryNotFound() throws Exception { + when(gitRepositoryManagerMock.openRepository(projectNameKey)) + .thenThrow(new RepositoryNotFoundException("not found")); + PushOne pushOne = createPushOne(null); + pushOne.addRef(PushOne.ALL_REFS); + pushOne.setToRetry(); + pushOne.run(); + assertThat(pushOne.isRetrying()).isFalse(); + } + private PushOne createPushOne(DynamicItem<ReplicationPushFilter> replicationPushFilter) { PushOne push = new PushOne(