summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaša Živkov <sasa.zivkov@sap.com>2019-05-15 10:13:34 +0200
committerDavid Pursehouse <dpursehouse@collab.net>2019-07-04 12:38:49 +0900
commit57077fda223d7c77c4df4ffd1054fb5237a7b919 (patch)
treee7a1fdb5d7550d32ce9de1ee299411f95730cd58
parentc3e8d153316035a0c24d8383be1cb2390752ab82 (diff)
When rescheduling due to in-flight push log also the in-flight task ID
When a push operation was rescheduled due to an in-flight push we logged a line like: [79bda07a] Rescheduling replication to https://host/foo.git to avoid collision with an in-flight push. This log was already useful but it didn't tell us which push task was actually in-flight. Add the ID of the in-flight push task to the log: [79bda07a] Rescheduling replication to https://host/foo.git to avoid collision with the in-flight push [80ceb18b]. This information is especially useful when a task gets repeatedly rescheduled and we need to identify the root cause of that. (cherry picked from commit f585eba0d21be222404b871bfe7a2b11e578eb14) Change-Id: I7866f964cab1e4f479b0d7d62ae4aac3019fab4b
-rw-r--r--src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java11
-rw-r--r--src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java13
-rw-r--r--src/main/java/com/googlesource/gerrit/plugins/replication/RunwayStatus.java49
3 files changed, 65 insertions, 8 deletions
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java b/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
index 0cee37c..40f9900 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
@@ -460,18 +460,19 @@ public class Destination {
return projectControlFactory.controlFor(project);
}
- boolean requestRunway(PushOne op) {
+ RunwayStatus requestRunway(PushOne op) {
synchronized (stateLock) {
if (op.wasCanceled()) {
- return false;
+ return RunwayStatus.canceled();
}
pending.remove(op.getURI());
- if (inFlight.containsKey(op.getURI())) {
- return false;
+ PushOne inFlightOp = inFlight.get(op.getURI());
+ if (inFlightOp != null) {
+ return RunwayStatus.denied(inFlightOp.getId());
}
inFlight.put(op.getURI(), op);
}
- return true;
+ return RunwayStatus.allowed();
}
void notifyFinished(PushOne op) {
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 20f5a0b..fdf6109 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
@@ -249,6 +249,10 @@ class PushOne implements ProjectRunnable, CanceledWhileRunning {
return states.toArray(new ReplicationState[states.size()]);
}
+ public int getId() {
+ return id;
+ }
+
void addStates(ListMultimap<String, ReplicationState> states) {
stateMap.putAll(states);
}
@@ -295,10 +299,13 @@ class PushOne implements ProjectRunnable, CanceledWhileRunning {
// created and scheduled for a future point in time.)
//
MDC.put(ID_MDC_KEY, IdGenerator.format(id));
- if (!pool.requestRunway(this)) {
- if (!canceled) {
+ RunwayStatus status = pool.requestRunway(this);
+ if (!status.isAllowed()) {
+ if (!status.isCanceled()) {
repLog.info(
- "Rescheduling replication to {} to avoid collision with an in-flight push.", uri);
+ "Rescheduling replication to {} to avoid collision with the in-flight push [{}].",
+ uri,
+ IdGenerator.format(status.getInFlightPushId()));
pool.reschedule(this, Destination.RetryReason.COLLISION);
}
return;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/RunwayStatus.java b/src/main/java/com/googlesource/gerrit/plugins/replication/RunwayStatus.java
new file mode 100644
index 0000000..bcb1e2f
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/RunwayStatus.java
@@ -0,0 +1,49 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.replication;
+
+public class RunwayStatus {
+ public static RunwayStatus allowed() {
+ return new RunwayStatus(true, 0);
+ }
+
+ public static RunwayStatus canceled() {
+ return new RunwayStatus(false, 0);
+ }
+
+ public static RunwayStatus denied(int inFlightPushId) {
+ return new RunwayStatus(false, inFlightPushId);
+ }
+
+ private final boolean allowed;
+ private final int inFlightPushId;
+
+ private RunwayStatus(boolean allowed, int inFlightPushId) {
+ this.allowed = allowed;
+ this.inFlightPushId = inFlightPushId;
+ }
+
+ public boolean isAllowed() {
+ return allowed;
+ }
+
+ public boolean isCanceled() {
+ return !allowed && inFlightPushId == 0;
+ }
+
+ public int getInFlightPushId() {
+ return inFlightPushId;
+ }
+}