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 {