Merge "Allow to set a max size for the in-memory code owner config cache"
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/TransientCodeOwnerConfigCache.java b/java/com/google/gerrit/plugins/codeowners/backend/TransientCodeOwnerConfigCache.java
index 61f014b..81eea89 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/TransientCodeOwnerConfigCache.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/TransientCodeOwnerConfigCache.java
@@ -17,6 +17,7 @@
import com.google.auto.value.AutoValue;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.BranchNameKey;
+import com.google.gerrit.plugins.codeowners.backend.config.CodeOwnersPluginConfiguration;
import com.google.gerrit.plugins.codeowners.metrics.CodeOwnerMetrics;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Inject;
@@ -38,14 +39,19 @@
public class TransientCodeOwnerConfigCache implements CodeOwnerConfigLoader {
private final GitRepositoryManager repoManager;
private final CodeOwners codeOwners;
+ private final Optional<Integer> maxCacheSize;
private final Counters counters;
private final HashMap<CacheKey, Optional<CodeOwnerConfig>> cache = new HashMap<>();
@Inject
TransientCodeOwnerConfigCache(
- GitRepositoryManager repoManager, CodeOwners codeOwners, CodeOwnerMetrics codeOwnerMetrics) {
+ CodeOwnersPluginConfiguration codeOwnersPluginConfiguration,
+ GitRepositoryManager repoManager,
+ CodeOwners codeOwners,
+ CodeOwnerMetrics codeOwnerMetrics) {
this.repoManager = repoManager;
this.codeOwners = codeOwners;
+ this.maxCacheSize = codeOwnersPluginConfiguration.getMaxCodeOwnerConfigCacheSize();
this.counters = new Counters(codeOwnerMetrics);
}
@@ -89,7 +95,9 @@
codeOwnerConfig = Optional.empty();
}
}
- cache.put(cacheKey, codeOwnerConfig);
+ if (!maxCacheSize.isPresent() || cache.size() < maxCacheSize.get()) {
+ cache.put(cacheKey, codeOwnerConfig);
+ }
return codeOwnerConfig;
}
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginConfiguration.java b/java/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginConfiguration.java
index 0855baf..3af457d 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginConfiguration.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginConfiguration.java
@@ -26,6 +26,7 @@
import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import java.util.Optional;
/**
* The configuration of the code-owners plugin.
@@ -48,6 +49,8 @@
@VisibleForTesting
static final String KEY_ENABLE_EXPERIMENTAL_REST_ENDPOINTS = "enableExperimentalRestEndpoints";
+ private static final String KEY_MAX_CODE_OWNER_CONFIG_CACHE_SIZE = "maxCodeOwnerConfigCacheSize";
+
private final CodeOwnersPluginConfigSnapshot.Factory codeOwnersPluginConfigSnapshotFactory;
private final String pluginName;
private final PluginConfigFactory pluginConfigFactory;
@@ -117,4 +120,31 @@
return false;
}
}
+
+ /**
+ * Gets the maximum size for the {@link
+ * com.google.gerrit.plugins.codeowners.backend.TransientCodeOwnerConfigCache}.
+ *
+ * @return the maximum cache size, {@link Optional#empty()} if the cache size is not limited
+ */
+ public Optional<Integer> getMaxCodeOwnerConfigCacheSize() {
+ try {
+ int maxCodeOwnerConfigCacheSize =
+ pluginConfigFactory
+ .getFromGerritConfig(pluginName)
+ .getInt(KEY_MAX_CODE_OWNER_CONFIG_CACHE_SIZE, /* defaultValue= */ 0);
+ return maxCodeOwnerConfigCacheSize > 0
+ ? Optional.of(maxCodeOwnerConfigCacheSize)
+ : Optional.empty();
+ } catch (IllegalArgumentException e) {
+ logger.atWarning().withCause(e).log(
+ "Value '%s' in gerrit.config (parameter plugin.%s.%s) is invalid.",
+ pluginConfigFactory
+ .getFromGerritConfig(pluginName)
+ .getString(KEY_MAX_CODE_OWNER_CONFIG_CACHE_SIZE),
+ pluginName,
+ KEY_MAX_CODE_OWNER_CONFIG_CACHE_SIZE);
+ return Optional.empty();
+ }
+ }
}
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginConfigurationTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginConfigurationTest.java
index 71c6849..ff53824 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginConfigurationTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/config/CodeOwnersPluginConfigurationTest.java
@@ -16,6 +16,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+import static com.google.gerrit.truth.OptionalSubject.assertThat;
import com.google.gerrit.acceptance.config.GerritConfig;
import com.google.gerrit.entities.Project;
@@ -88,4 +89,29 @@
public void experimentalRestEndpointsNotEnabled_invalidConfig() throws Exception {
assertThat(codeOwnersPluginConfiguration.areExperimentalRestEndpointsEnabled()).isFalse();
}
+
+ @Test
+ public void codeOwnerConfigCacheSizeIsUnlimitedByDefault() throws Exception {
+ assertThat(codeOwnersPluginConfiguration.getMaxCodeOwnerConfigCacheSize()).isEmpty();
+ }
+
+ @Test
+ @GerritConfig(name = "plugin.code-owners.maxCodeOwnerConfigCacheSize", value = "0")
+ public void codeOwnerConfigCacheSizeIsUnlimited() throws Exception {
+ assertThat(codeOwnersPluginConfiguration.getMaxCodeOwnerConfigCacheSize()).isEmpty();
+ }
+
+ @Test
+ @GerritConfig(name = "plugin.code-owners.maxCodeOwnerConfigCacheSize", value = "10")
+ public void codeOwnerConfigCacheSizeIsLimited() throws Exception {
+ assertThat(codeOwnersPluginConfiguration.getMaxCodeOwnerConfigCacheSize())
+ .value()
+ .isEqualTo(10);
+ }
+
+ @Test
+ @GerritConfig(name = "plugin.code-owners.maxCodeOwnerConfigCacheSize", value = "invalid")
+ public void maxCodeOwnerConfigCacheSize_invalidConfig() throws Exception {
+ assertThat(codeOwnersPluginConfiguration.getMaxCodeOwnerConfigCacheSize()).isEmpty();
+ }
}
diff --git a/resources/Documentation/config.md b/resources/Documentation/config.md
index a94cf63..6d45d59 100644
--- a/resources/Documentation/config.md
+++ b/resources/Documentation/config.md
@@ -398,6 +398,14 @@
in `@PLUGIN@.config`.\
By default `100`.
+<a id="pluginCodeOwnersMaxCodeOwnerConfigCacheSize">plugin.@PLUGIN@.maxCodeOwnerConfigCacheSize</a>
+: When computing code owner file statuses for a change (e.g. to compute
+ the results for the code owners submit rule) parsed code owner config
+ files are cached in memory for the time of the request.\
+ This configuration parameter allows to set a limit for the number of
+ code owner config files that are cached per request.\
+ By default `0` (unlimited).
+
# <a id="projectConfiguration">Project configuration in @PLUGIN@.config</a>
<a id="codeOwnersDisabled">codeOwners.disabled</a>