From 9503a2e582c0103fb04aa8266dd84f365f44b6b6 Mon Sep 17 00:00:00 2001 From: David Ostrovsky Date: Sun, 3 Jan 2016 18:49:26 +0100 Subject: [PATCH] Use subscribe pattern to avoid eager stream-events materialization Now that memoized supplier pattern is used to reduce the resource consumption in firing event machinery and the data is only retrieved when the events are really consumed, it's worth to provide an option to optimize stream events consumption to avoid materialization of events that are not needed. Stream events are used by IRC publish libraries and CI integration solutions, e.g. Zuul, where only a subset of event types is used. Add --subscribe option and allow to specify event types to consume while ignore all other events. Test Plan: Non retrieval of data with default gerrit install + reviewers plugin + Jenkins Gerrit Trigger plugin. 1. install gerrit with all core plugins 2. install reviewers plugin 3. set up stream event for Jenkins Gerrit Trigger plugin, but use new option to subscribe to only "draft-published", "patchset-created" and "ref-replicated" (exposed by replication plugin) events 4. create a group_100 that contains 100 users 5. add a reviewer to a change and select the group_100 Without this change hundreds of SQL select statements are executed in vain. That's because 100 ChangeEvent instances are created and multiple SQL select statements are executed per instance. With this change exact 0 select SQL statements are executed. Memoized suppliers are created but because this stream event type "reviewer-added" wasn't subscribed to all these events are ignored and thus not materialized. Change-Id: I525499c26812bb09ba0cddf9f0e8eb0fb822c15b --- Documentation/cmd-stream-events.txt | 15 +++++++++++++++ .../google/gerrit/sshd/commands/StreamEvents.java | 12 +++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Documentation/cmd-stream-events.txt b/Documentation/cmd-stream-events.txt index dcdbb0717a..ee645c176b 100644 --- a/Documentation/cmd-stream-events.txt +++ b/Documentation/cmd-stream-events.txt @@ -26,6 +26,14 @@ link:access-control.html#capability_streamEvents[the 'Stream Events' global capa == SCRIPTING This command is intended to be used in scripts. +== OPTIONS +--subscribe|-s:: + Type of the event to subscribe to. Multiple --subscribe options + may be specified to subscribe to multiple events. When this option + is provided, only subscribed events are emitted and all other + events are ignored. When this option is omitted, all events are + emitted. + == EXAMPLES ==== @@ -34,6 +42,13 @@ This command is intended to be used in scripts. {"type":"comment-added",change:{"project":"tools/gerrit", ...}, ...} ==== +Only subscribe to specific event types: + +==== + $ ssh -p 29418 review.example.com gerrit stream-events \ + -s draft-published -s patchset-created -s ref-replicated +==== + == SCHEMA The JSON messages consist of nested objects referencing the *change*, *patchSet*, *account* involved, and other attributes as appropriate. diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/StreamEvents.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/StreamEvents.java index 91757585ef..734136f4ae 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/StreamEvents.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/StreamEvents.java @@ -38,10 +38,13 @@ import com.google.gson.JsonSerializer; import com.google.inject.Inject; import org.apache.sshd.server.Environment; +import org.kohsuke.args4j.Option; import java.io.IOException; import java.io.PrintWriter; import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; @@ -55,6 +58,10 @@ final class StreamEvents extends BaseCommand { /** Number of events to write before yielding off the thread. */ private static final int BATCH_SIZE = 32; + @Option(name = "--subscribe", aliases = {"-s"}, metaVar = "SUBSCRIBE", + usage = "subscribe to specific stream-events") + private List subscribedToEvents = new ArrayList<>(); + @Inject private IdentifiedUser currentUser; @@ -87,7 +94,10 @@ final class StreamEvents extends BaseCommand { private final EventListener listener = new EventListener() { @Override public void onEvent(final Event event) { - offer(event); + if (subscribedToEvents.isEmpty() + || subscribedToEvents.contains(event.getType())) { + offer(event); + } } };