Allow to enable/disable push/pull replication filters
The multi-site plugin had always enabled all replication filtering with
the checking of their global-refdb status. Although it is a good default
to have, the lack of flexibility brought some additional performance
issues when running unneeded checks of hundreds of thousands of refs
against the global-refdb. Example: the replication endpoint is not
Gerrit or is a Gerrit replica, therefore there is no need to integrate
and check with the global-refdb consistency, because the endpoint won't
be tracked under it anyway.
On Cloud environments where the global-refdb is provided as a service,
the consumption of the APIs is very expensive and can also be capped or
rate-limited, causing potential outages due to unneeded calls.
Introduce two new settings for enabling/disabling the filtering
individually for the push or pull-replication plugins.
Example:
[ref-database]
pushReplicationFilterClassEnabled = false
Change-Id: I1989f3bbc8c257f9bb5847e7d3c7755464e2cf3a
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
index a7a05d3..dd694f6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
@@ -58,6 +58,8 @@
private static final String REPLICATION_LAG_REFRESH_INTERVAL = "replicationLagRefreshInterval";
private static final String REPLICATION_LAG_ENABLED = "replicationLagEnabled";
private static final Duration REPLICATION_LAG_REFRESH_INTERVAL_DEFAULT = Duration.ofSeconds(60);
+ private static final String PUSH_REPLICATION_FILTER_ENABLED = "pushReplicationFilterEnabled";
+ private static final String PULL_REPLICATION_FILTER_ENABLED = "pullReplicationFilterEnabled";
private static final String REPLICATION_CONFIG = "replication.config";
// common parameters to cache and index sections
@@ -79,6 +81,8 @@
private final Config multiSiteConfig;
private final Supplier<Duration> replicationLagRefreshInterval;
private final Supplier<Boolean> replicationLagEnabled;
+ private final Supplier<Boolean> pushReplicationFilterEnabled;
+ private final Supplier<Boolean> pullReplicationFilterEnabled;
@Inject
Configuration(SitePaths sitePaths) {
@@ -118,6 +122,19 @@
lazyMultiSiteCfg
.get()
.getBoolean(REF_DATABASE, null, REPLICATION_LAG_ENABLED, true));
+
+ pushReplicationFilterEnabled =
+ memoize(
+ () ->
+ lazyMultiSiteCfg
+ .get()
+ .getBoolean(REF_DATABASE, null, PUSH_REPLICATION_FILTER_ENABLED, true));
+ pullReplicationFilterEnabled =
+ memoize(
+ () ->
+ lazyMultiSiteCfg
+ .get()
+ .getBoolean(REF_DATABASE, null, PULL_REPLICATION_FILTER_ENABLED, true));
}
public Config getMultiSiteConfig() {
@@ -160,6 +177,14 @@
return replicationLagEnabled.get();
}
+ public boolean pushReplicationFilterEnabled() {
+ return pushReplicationFilterEnabled.get();
+ }
+
+ public boolean pullRepllicationFilterEnabled() {
+ return pullReplicationFilterEnabled.get();
+ }
+
public Collection<Message> validate() {
return replicationConfigValidation.get();
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java
index db06c9f..3ced8c6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java
@@ -35,14 +35,10 @@
public class PluginModule extends LifecycleModule {
private static final FluentLogger log = FluentLogger.forEnclosingClass();
- private static final String[] FILTER_MODULES_CLASS_NAMES =
- new String[] {
- /* Class names are defined as String for avoiding this class failing to load
- * if either replication or pull-replication plugins are missing.
- */
- "com.googlesource.gerrit.plugins.multisite.validation.PullReplicationFilterModule",
- "com.googlesource.gerrit.plugins.multisite.validation.PushReplicationFilterModule"
- };
+ public static final String PULL_REPLICATION_FILTER_MODULE =
+ "com.googlesource.gerrit.plugins.multisite.validation.PullReplicationFilterModule";
+ public static final String PUSH_REPLICATION_FILTER_MODULE =
+ "com.googlesource.gerrit.plugins.multisite.validation.PushReplicationFilterModule";
private final Configuration config;
private final WorkQueue workQueue;
@@ -89,25 +85,33 @@
private Iterable<AbstractModule> detectFilterModules() {
ImmutableList.Builder<AbstractModule> filterModulesBuilder = ImmutableList.builder();
- for (String filterClassName : FILTER_MODULES_CLASS_NAMES) {
- try {
- @SuppressWarnings("unchecked")
- Class<AbstractModule> filterClass = (Class<AbstractModule>) Class.forName(filterClassName);
-
- AbstractModule filterModule = parentInjector.getInstance(filterClass);
- // Check if the filterModule would be valid for creating a child Guice Injector
- parentInjector.createChildInjector(filterModule);
-
- filterModulesBuilder.add(filterModule);
- } catch (NoClassDefFoundError | ClassNotFoundException e) {
- log.atFine().withCause(e).log(
- "Not loading %s because of missing the associated replication plugin", filterClassName);
- } catch (Exception e) {
- throw new ProvisionException(
- "Unable to instantiate replication filter " + filterClassName, e);
- }
+ if (config.pushReplicationFilterEnabled()) {
+ bindReplicationFilterClass(PUSH_REPLICATION_FILTER_MODULE, filterModulesBuilder);
+ }
+ if (config.pullRepllicationFilterEnabled()) {
+ bindReplicationFilterClass(PULL_REPLICATION_FILTER_MODULE, filterModulesBuilder);
}
return filterModulesBuilder.build();
}
+
+ private void bindReplicationFilterClass(
+ String filterClassName, ImmutableList.Builder<AbstractModule> filterModulesBuilder) {
+ try {
+ @SuppressWarnings("unchecked")
+ Class<AbstractModule> filterClass = (Class<AbstractModule>) Class.forName(filterClassName);
+
+ AbstractModule filterModule = parentInjector.getInstance(filterClass);
+ // Check if the filterModule would be valid for creating a child Guice Injector
+ parentInjector.createChildInjector(filterModule);
+
+ filterModulesBuilder.add(filterModule);
+ } catch (NoClassDefFoundError | ClassNotFoundException e) {
+ log.atWarning().withCause(e).log(
+ "Not loading %s because of missing the associated replication plugin", filterClassName);
+ } catch (Exception e) {
+ throw new ProvisionException(
+ "Unable to instantiate replication filter " + filterClassName, e);
+ }
+ }
}
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 7547fd9..d7f72aa 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -95,6 +95,16 @@
: Enable the use of a shared ref-database
Defaults: true
+```ref-database.pushReplicationFilterClassEnabled```
+: Enable the filtering of push replication events checking their
+ up-to-date status with the global-refdb.
+ Defaults: true
+
+```ref-database.pullReplicationFilterClassEnabled```
+: Enable the filtering of pull replication events checking their
+ up-to-date status with the global-refdb.
+ Defaults: true
+
```ref-database.replicationLagEnabled```
: Enable the metrics to trace the auto-replication lag between sites
updating the `refs/multi-site/version/*` to the _epoch_ timestamp in