Optionally create review notes asynchronously
Review notes are generally not vital to a server's operation and/or
may be created by one of several GitReferenceUpdatedListeners on the
blocking MergeOp path, so give administrators the option to run them
asynchronously.
Change-Id: I1f6c30f9e6fd38e8bd8574122d19d3a4d0b0dd18
diff --git a/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/CreateReviewNotes.java b/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/CreateReviewNotes.java
index 976a5b1..42374ac 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/CreateReviewNotes.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/CreateReviewNotes.java
@@ -225,6 +225,9 @@
private void createCodeReviewNote(Change change, PatchSet ps,
HeaderFormatter fmt) throws OrmException, NoSuchChangeException {
+ // This races with the label normalization/writeback done by MergeOp. It may
+ // repeat some work, but results should be identical except in the case of
+ // an additional race with a permissions change.
List<PatchSetApproval> approvals = labelNormalizer.normalize(
change, reviewDb.patchSetApprovals().byPatchSet(ps.getId()).toList());
PatchSetApproval submit = null;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/RefUpdateListener.java b/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/RefUpdateListener.java
index 8dca4ad..7755776 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/RefUpdateListener.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/RefUpdateListener.java
@@ -18,6 +18,7 @@
import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
+import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.slf4j.Logger;
@@ -26,31 +27,77 @@
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.git.ProjectRunnable;
+import com.google.gerrit.server.git.WorkQueue;
+import com.google.gerrit.server.util.RequestScopePropagator;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
class RefUpdateListener implements GitReferenceUpdatedListener {
- private static final Logger log =
- LoggerFactory.getLogger(RefUpdateListener.class);
+ private static final Logger log = LoggerFactory
+ .getLogger(RefUpdateListener.class);
private final CreateReviewNotes.Factory reviewNotesFactory;
private final SchemaFactory<ReviewDb> schema;
private final GitRepositoryManager repoManager;
+ private final WorkQueue workQueue;
+ private final RequestScopePropagator requestScopePropagator;
+ private final boolean async;
@Inject
RefUpdateListener(final CreateReviewNotes.Factory reviewNotesFactory,
final SchemaFactory<ReviewDb> schema,
- final GitRepositoryManager repoManager) {
+ final GitRepositoryManager repoManager, final WorkQueue workQueue,
+ final RequestScopePropagator requestScopePropagator,
+ @GerritServerConfig final Config config) {
this.reviewNotesFactory = reviewNotesFactory;
this.schema = schema;
this.repoManager = repoManager;
+ this.workQueue = workQueue;
+ this.requestScopePropagator = requestScopePropagator;
+ this.async = config.getBoolean("reviewnotes", null, "async", false);
}
@Override
- public void onGitReferenceUpdated(Event e) {
+ public void onGitReferenceUpdated(final Event e) {
+ if (async) {
+ workQueue.getDefaultQueue().submit(
+ requestScopePropagator.wrap(new ProjectRunnable() {
+ @Override
+ public void run() {
+ createReviewNotes(e);
+ }
+
+ @Override
+ public Project.NameKey getProjectNameKey() {
+ return new Project.NameKey(e.getProjectName());
+ }
+
+ @Override
+ public String getRemoteName() {
+ return null;
+ }
+
+ @Override
+ public boolean hasCustomizedPrint() {
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "create-review-notes";
+ }
+ }));
+ } else {
+ createReviewNotes(e);
+ }
+ }
+
+ private void createReviewNotes(Event e) {
Project.NameKey projectName = new Project.NameKey(e.getProjectName());
Repository git;
try {