Merge branch 'stable-3.11' into stable-3.12

* stable-3.11:
  Do not notify failures on collisions
  Fixed erroneous increment of the rescheduled metric
  Ensure failures are only incremented in RunnableWithMetrics
  Move ProjectDeletionAction/CacheDeleteHandler PullReplicationModule

Change-Id: Idf22185207dc94bd184be6e4130e526ef16a2ca5
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/FetchOne.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/FetchOne.java
index 9f94a6a..b194f2c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/FetchOne.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/FetchOne.java
@@ -95,6 +95,7 @@
   private final Set<TransportException> fetchFailures = Sets.newHashSetWithExpectedSize(4);
   private boolean fetchAllRefs;
   private Repository git;
+  private boolean isCollision;
   private boolean retrying;
   private int retryCount;
   private final int maxRetries;
@@ -292,7 +293,7 @@
   }
 
   private void statesCleanUp() {
-    if (!stateMap.isEmpty() && !isRetrying()) {
+    if (!stateMap.isEmpty() && !isRetrying() && !isCollision) {
       for (Map.Entry<FetchRefSpec, ReplicationState> entry : stateMap.entries()) {
         entry
             .getValue()
@@ -348,6 +349,7 @@
     // we start replication (instead a new instance, with the same URI, is
     // created and scheduled for a future point in time.)
     //
+    isCollision = false;
     if (replicationType == ReplicationType.ASYNC && !pool.requestRunway(this)) {
       if (!canceled) {
         repLog.info(
@@ -357,6 +359,7 @@
             uri,
             pool.getInFlight(getURI()).map(FetchOne::getTaskIdHex).orElse("<unknown>"));
         pool.reschedule(this, Source.RetryReason.COLLISION);
+        isCollision = true;
       }
       return;
     }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/Source.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/Source.java
index b1d553d..0a75288 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/Source.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/Source.java
@@ -641,8 +641,6 @@
                   fetchOp.getTaskIdHex(), fetchOp.getURI(), pendingFetchOp.getTaskIdHex()),
               fetchOp.getStatesAsArray());
 
-          queueMetrics.incrementTaskRescheduled(this);
-
         } else {
           // The one pending is one that is NOT retrying, it was just
           // scheduled believing no problem would happen. The one pending
@@ -682,9 +680,8 @@
                   "[%s] Merging the pending fetch from [%s] with task [%s] and rescheduling",
                   pendingFetchOp.getTaskIdHex(), pendingFetchOp.getURI(), fetchOp.getTaskIdHex()),
               pendingFetchOp.getStatesAsArray());
-
-          queueMetrics.incrementTaskMerged(this);
         }
+        queueMetrics.incrementTaskMerged(this);
       }
 
       if (pendingFetchOp == null || !pendingFetchOp.isRetrying()) {
@@ -705,8 +702,6 @@
                     ? RefUpdate.Result.NOT_ATTEMPTED
                     : RefUpdate.Result.REJECTED_OTHER_REASON;
             postReplicationFailedEvent(fetchOp, trackingRefUpdate);
-            queueMetrics.incrementTaskFailed(this);
-            queueMetrics.incrementFetchRefsFailed(this, fetchOp);
 
             if (fetchOp.setToRetry()) {
               postReplicationScheduledEvent(fetchOp);