Merge branch 'stable-2.12'
* stable-2.12:
Revert "Replicate HEAD reference when replicating a project"
Fetch parent groups of the authGroups
Replicate HEAD reference when replicating a project
Revert "Remove obsolete remote.NAME.timeout from config documentation"
Add logging of cancelled replication events
Change-Id: I159cba10662e7aaa6cd8d2f7b121e99e87ac24ce
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 e267da3..120c94c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
@@ -264,7 +264,7 @@
if (e == null) {
try (Repository git = gitManager.openRepository(project)) {
try {
- Ref head = git.getRef(Constants.HEAD);
+ Ref head = git.exactRef(Constants.HEAD);
if (head != null
&& head.isSymbolic()
&& RefNames.REFS_CONFIG.equals(head.getLeaf().getName())) {
@@ -380,6 +380,7 @@
pool.schedule(pushOp, delay, TimeUnit.SECONDS);
break;
case TRANSPORT_ERROR:
+ case REPOSITORY_MISSING:
default:
pushOp.setToRetry();
pool.schedule(pushOp, retryDelay, TimeUnit.MINUTES);
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 4a2d01b..002361a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
@@ -15,6 +15,7 @@
package com.googlesource.gerrit.plugins.replication;
import static com.googlesource.gerrit.plugins.replication.ReplicationQueue.repLog;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
import com.google.common.base.Throwables;
import com.google.common.collect.LinkedListMultimap;
@@ -22,8 +23,8 @@
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
-import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
+import com.google.gerrit.metrics.Timer1;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
@@ -111,6 +112,7 @@
private int lockRetryCount;
private final int id;
private final long createdAt;
+ private final ReplicationMetrics metrics;
@Inject
PushOne(final GitRepositoryManager grm,
@@ -124,6 +126,7 @@
final ReplicationQueue rq,
final IdGenerator ig,
final ReplicationStateListener sl,
+ final ReplicationMetrics m,
@Assisted final Project.NameKey d,
@Assisted final URIish u) {
gitManager = grm;
@@ -141,7 +144,8 @@
maxLockRetries = pool.getLockErrorMaxRetries();
id = ig.next();
stateLog = sl;
- createdAt = TimeUtil.nowMs();
+ createdAt = System.nanoTime();
+ metrics = m;
}
@Override
@@ -281,15 +285,17 @@
return;
}
- long startedAt = TimeUtil.nowMs();
repLog.info("Replication to " + uri + " started...");
+ Timer1.Context context = metrics.start(config.getName());
try {
+ long startedAt = context.getStartTime();
git = gitManager.openRepository(projectName);
runImpl();
- long finishedAt = TimeUtil.nowMs();
+ long elapsed = NANOSECONDS.toMillis(context.stop());
+ long delay = NANOSECONDS.toMillis(startedAt - createdAt);
repLog.info("Replication to " + uri + " completed in "
- + (finishedAt - startedAt) + "ms, "
- + (startedAt - createdAt) + "ms delay, " + retryCount + " retries");
+ + (elapsed) + "ms, "
+ + (delay) + "ms delay, " + retryCount + " retries");
} catch (RepositoryNotFoundException e) {
stateLog.error("Cannot replicate " + projectName
+ "; Local repository error: "
@@ -350,7 +356,7 @@
private void createRepository() {
if (pool.isCreateMissingRepos()) {
try {
- final Ref head = git.getRef(Constants.HEAD);
+ final Ref head = git.exactRef(Constants.HEAD);
if (replicationQueue.createProject(projectName, head != null ? head.getName() : null)) {
repLog.warn("Missing repository created; retry replication to " + uri);
pool.reschedule(this, Destination.RetryReason.REPOSITORY_MISSING);
@@ -369,18 +375,10 @@
}
private void runImpl() throws IOException {
- Transport tn = Transport.open(git, uri);
PushResult res;
- try {
+ try (Transport tn = Transport.open(git, uri)) {
res = pushVia(tn);
- } finally {
- try {
- tn.close();
- } catch (Throwable e2) {
- repLog.warn("Unexpected error while closing " + uri, e2);
- }
}
-
updateStates(res.getRemoteUpdates());
}
@@ -500,11 +498,8 @@
private Map<String, Ref> listRemote(Transport tn)
throws NotSupportedException, TransportException {
- FetchConnection fc = tn.openFetch();
- try {
+ try (FetchConnection fc = tn.openFetch()) {
return fc.getRefsMap();
- } finally {
- fc.close();
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/RefReplicatedEvent.java b/src/main/java/com/googlesource/gerrit/plugins/replication/RefReplicatedEvent.java
index f200194..05936dd 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/RefReplicatedEvent.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/RefReplicatedEvent.java
@@ -23,6 +23,8 @@
import org.eclipse.jgit.transport.RemoteRefUpdate.Status;
public class RefReplicatedEvent extends RefEvent {
+ static final String TYPE = "ref-replicated";
+
public final String project;
public final String ref;
public final String targetNode;
@@ -31,7 +33,7 @@
public RefReplicatedEvent(String project, String ref, String targetNode,
RefPushResult status, RemoteRefUpdate.Status refStatus) {
- super("ref-replicated");
+ super(TYPE);
this.project = project;
this.ref = ref;
this.targetNode = targetNode;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/RefReplicationDoneEvent.java b/src/main/java/com/googlesource/gerrit/plugins/replication/RefReplicationDoneEvent.java
index fe92bc8..cde3e9e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/RefReplicationDoneEvent.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/RefReplicationDoneEvent.java
@@ -18,12 +18,14 @@
import com.google.gerrit.server.events.RefEvent;
public class RefReplicationDoneEvent extends RefEvent {
+ static final String TYPE = "ref-replication-done";
+
public final String project;
public final String ref;
public final int nodesCount;
public RefReplicationDoneEvent(String project, String ref, int nodesCount) {
- super("ref-replication-done");
+ super(TYPE);
this.project = project;
this.ref = ref;
this.nodesCount = nodesCount;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationMetrics.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationMetrics.java
new file mode 100644
index 0000000..ad266da
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationMetrics.java
@@ -0,0 +1,42 @@
+// Copyright (C) 2015 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;
+
+import com.google.gerrit.metrics.Description;
+import com.google.gerrit.metrics.Field;
+import com.google.gerrit.metrics.MetricMaker;
+import com.google.gerrit.metrics.Timer1;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+@Singleton
+public class ReplicationMetrics {
+ Timer1<String> executionTime;
+
+ @Inject
+ ReplicationMetrics(MetricMaker metricMaker) {
+ executionTime = metricMaker.newTimer(
+ "replication_latency",
+ new Description("Time spent pushing to remote destination.")
+ .setCumulative()
+ .setUnit(Description.Units.SECONDS),
+ Field.ofString("destination"));
+ }
+
+ Timer1.Context start(String name) {
+ return executionTime.start(name);
+ }
+
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationModule.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationModule.java
index a5d0b82..e813885 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationModule.java
@@ -14,7 +14,6 @@
package com.googlesource.gerrit.plugins.replication;
-import static com.googlesource.gerrit.plugins.replication.ReplicationState.RefPushResult.SUCCEEDED;
import static com.googlesource.gerrit.plugins.replication.StartReplicationCapability.START_REPLICATION;
import com.google.gerrit.extensions.annotations.Exports;
@@ -31,8 +30,6 @@
import com.google.inject.assistedinject.FactoryModuleBuilder;
import com.google.inject.internal.UniqueAnnotations;
-import org.eclipse.jgit.transport.RemoteRefUpdate;
-
class ReplicationModule extends AbstractModule {
@Override
@@ -66,8 +63,7 @@
bind(ReplicationConfig.class).to(AutoReloadConfigDecorator.class);
bind(ReplicationStateListener.class).to(ReplicationStateLogger.class);
- EventTypes.registerClass(new RefReplicatedEvent(null, null, null,
- SUCCEEDED, RemoteRefUpdate.Status.OK));
- EventTypes.registerClass(new RefReplicationDoneEvent(null, null, 0));
+ EventTypes.register(RefReplicatedEvent.TYPE, RefReplicatedEvent.class);
+ EventTypes.register(RefReplicationDoneEvent.TYPE, RefReplicationDoneEvent.class);
}
}