Merge changes from topic "asynchronous_fetch" into stable-3.1
* changes:
Add replication delay for asynchronous fetch calls
Allow asynchronous fetch calls
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/Context.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/Context.java
new file mode 100644
index 0000000..34bf3d2
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/Context.java
@@ -0,0 +1,39 @@
+// Copyright (C) 2021 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.pull;
+
+/**
+ * Allows to tag event as local to avoid consuming remote events.
+ *
+ * <p>TODO: Gerrit v3.1 doesn't have concept of the instanceId so ThreadLocal must be used. From
+ * Gerrit v3.2 replace ThreadLocal with instanceId.
+ */
+public class Context {
+ private static final ThreadLocal<Boolean> localEvent = ThreadLocal.withInitial(() -> false);
+
+ private Context() {}
+
+ public static Boolean isLocalEvent() {
+ return localEvent.get();
+ }
+
+ public static void setLocalEvent(Boolean b) {
+ localEvent.set(b);
+ }
+
+ public static void unsetLocalEvent() {
+ localEvent.remove();
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/FetchResultProcessing.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/FetchResultProcessing.java
index 2d51239..ab16318 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/FetchResultProcessing.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/FetchResultProcessing.java
@@ -118,12 +118,15 @@
}
writeStdOut(sb.toString());
try {
+ Context.setLocalEvent(true);
dispatcher.postEvent(
new FetchRefReplicatedEvent(
project, ref, resolveNodeName(uri), status, refUpdateResult));
} catch (PermissionBackendException e) {
logger.atSevere().withCause(e).log(
"Cannot post event for ref '%s', project %s", ref, project);
+ } finally {
+ Context.unsetLocalEvent();
}
}
@@ -200,9 +203,12 @@
private void postEvent(RefEvent event) {
try {
+ Context.setLocalEvent(true);
dispatcher.postEvent(event);
} catch (PermissionBackendException e) {
logger.atSevere().withCause(e).log("Cannot post event");
+ } finally {
+ Context.unsetLocalEvent();
}
}
}
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 3847426..ea2ce32 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
@@ -765,15 +765,20 @@
private void postReplicationFailedEvent(FetchOne fetchOp, RefUpdate.Result result) {
Project.NameKey project = fetchOp.getProjectNameKey();
String sourceNode = resolveNodeName(fetchOp.getURI());
- for (String ref : fetchOp.getRefs()) {
- FetchRefReplicatedEvent event =
- new FetchRefReplicatedEvent(
- project.get(), ref, sourceNode, ReplicationState.RefFetchResult.FAILED, result);
- try {
- eventDispatcher.get().postEvent(BranchNameKey.create(project, ref), event);
- } catch (PermissionBackendException e) {
- repLog.error("error posting event", e);
+ try {
+ Context.setLocalEvent(true);
+ for (String ref : fetchOp.getRefs()) {
+ FetchRefReplicatedEvent event =
+ new FetchRefReplicatedEvent(
+ project.get(), ref, sourceNode, ReplicationState.RefFetchResult.FAILED, result);
+ try {
+ eventDispatcher.get().postEvent(BranchNameKey.create(project, ref), event);
+ } catch (PermissionBackendException e) {
+ repLog.error("error posting event", e);
+ }
}
+ } finally {
+ Context.unsetLocalEvent();
}
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/ApplyObjectCommand.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/ApplyObjectCommand.java
index ac7e79b..276aa16 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/ApplyObjectCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/ApplyObjectCommand.java
@@ -26,6 +26,7 @@
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.replication.pull.ApplyObjectMetrics;
+import com.googlesource.gerrit.plugins.replication.pull.Context;
import com.googlesource.gerrit.plugins.replication.pull.FetchRefReplicatedEvent;
import com.googlesource.gerrit.plugins.replication.pull.PullReplicationStateLogger;
import com.googlesource.gerrit.plugins.replication.pull.ReplicationState;
@@ -78,6 +79,7 @@
long elapsed = NANOSECONDS.toMillis(context.stop());
try {
+ Context.setLocalEvent(true);
eventDispatcher
.get()
.postEvent(
@@ -90,6 +92,8 @@
} catch (PermissionBackendException e) {
logger.atSevere().withCause(e).log(
"Cannot post event for ref '%s', project %s", refName, name);
+ } finally {
+ Context.unsetLocalEvent();
}
if (!isSuccessful(refUpdateState.getResult())) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/event/FetchRefReplicatedEventHandler.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/event/FetchRefReplicatedEventHandler.java
index fc96394..a618e16 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/event/FetchRefReplicatedEventHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/event/FetchRefReplicatedEventHandler.java
@@ -17,10 +17,12 @@
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Project;
+import com.google.gerrit.entities.RefNames;
import com.google.gerrit.server.events.Event;
import com.google.gerrit.server.events.EventListener;
import com.google.gerrit.server.index.change.ChangeIndexer;
import com.google.inject.Inject;
+import com.googlesource.gerrit.plugins.replication.pull.Context;
import com.googlesource.gerrit.plugins.replication.pull.FetchRefReplicatedEvent;
import com.googlesource.gerrit.plugins.replication.pull.ReplicationState;
@@ -35,18 +37,21 @@
@Override
public void onEvent(Event event) {
- if (event instanceof FetchRefReplicatedEvent) {
+ if (event instanceof FetchRefReplicatedEvent && isLocalEvent()) {
FetchRefReplicatedEvent fetchRefReplicatedEvent = (FetchRefReplicatedEvent) event;
+ if (!RefNames.isNoteDbMetaRef(fetchRefReplicatedEvent.getRefName())
+ || !fetchRefReplicatedEvent
+ .getStatus()
+ .equals(ReplicationState.RefFetchResult.SUCCEEDED.toString())) {
+ return;
+ }
+
Project.NameKey projectNameKey = fetchRefReplicatedEvent.getProjectNameKey();
logger.atFine().log(
"Indexing ref '%s' for project %s",
fetchRefReplicatedEvent.getRefName(), projectNameKey.get());
-
Change.Id changeId = Change.Id.fromRef(fetchRefReplicatedEvent.getRefName());
- if (changeId != null
- && fetchRefReplicatedEvent
- .getStatus()
- .equals(ReplicationState.RefFetchResult.SUCCEEDED.toString())) {
+ if (changeId != null) {
changeIndexer.index(projectNameKey, changeId);
} else {
logger.atWarning().log(
@@ -55,4 +60,8 @@
}
}
}
+
+ private boolean isLocalEvent() {
+ return Context.isLocalEvent();
+ }
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/event/FetchRefReplicatedEventHandlerTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/event/FetchRefReplicatedEventHandlerTest.java
index 1d87195..e528eca 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/event/FetchRefReplicatedEventHandlerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/event/FetchRefReplicatedEventHandlerTest.java
@@ -24,6 +24,7 @@
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.index.change.ChangeIndexer;
+import com.googlesource.gerrit.plugins.replication.pull.Context;
import com.googlesource.gerrit.plugins.replication.pull.FetchRefReplicatedEvent;
import com.googlesource.gerrit.plugins.replication.pull.ReplicationState;
import org.eclipse.jgit.lib.RefUpdate;
@@ -45,6 +46,26 @@
Project.NameKey projectNameKey = Project.nameKey("testProject");
String ref = "refs/changes/41/41/meta";
Change.Id changeId = Change.Id.fromRef(ref);
+ try {
+ Context.setLocalEvent(true);
+ fetchRefReplicatedEventHandler.onEvent(
+ new FetchRefReplicatedEvent(
+ projectNameKey.get(),
+ ref,
+ "aSourceNode",
+ ReplicationState.RefFetchResult.SUCCEEDED,
+ RefUpdate.Result.FAST_FORWARD));
+ verify(changeIndexerMock, times(1)).index(eq(projectNameKey), eq(changeId));
+ } finally {
+ Context.unsetLocalEvent();
+ }
+ }
+
+ @Test
+ public void onEventShouldNotIndexIfNotLocalEvent() {
+ Project.NameKey projectNameKey = Project.nameKey("testProject");
+ String ref = "refs/changes/41/41/meta";
+ Change.Id changeId = Change.Id.fromRef(ref);
fetchRefReplicatedEventHandler.onEvent(
new FetchRefReplicatedEvent(
projectNameKey.get(),
@@ -52,7 +73,22 @@
"aSourceNode",
ReplicationState.RefFetchResult.SUCCEEDED,
RefUpdate.Result.FAST_FORWARD));
- verify(changeIndexerMock, times(1)).index(eq(projectNameKey), eq(changeId));
+ verify(changeIndexerMock, never()).index(eq(projectNameKey), eq(changeId));
+ }
+
+ @Test
+ public void onEventShouldIndexOnlyMetaRef() {
+ Project.NameKey projectNameKey = Project.nameKey("testProject");
+ String ref = "refs/changes/41/41/1";
+ Change.Id changeId = Change.Id.fromRef(ref);
+ fetchRefReplicatedEventHandler.onEvent(
+ new FetchRefReplicatedEvent(
+ projectNameKey.get(),
+ ref,
+ "aSourceNode",
+ ReplicationState.RefFetchResult.SUCCEEDED,
+ RefUpdate.Result.FAST_FORWARD));
+ verify(changeIndexerMock, never()).index(eq(projectNameKey), eq(changeId));
}
@Test