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
This commit is contained in:
David Ostrovsky
2016-01-03 18:49:26 +01:00
parent b612e23b45
commit 9503a2e582
2 changed files with 26 additions and 1 deletions

View File

@@ -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.

View File

@@ -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<String> 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);
}
}
};