Replace project cache with GerritApi for listing projects
When rendering the number of projects metrics, use an
inexpensive project list instead of loading all projects
in cache, leveraging an internal user context.
Also honour the grace period configuration of the plugin
so that the new metric will respect the update frequency
configured without generating extra workload on the system.
If the metrics is requested more often, return a memoized
value from the earlier executions.
Change-Id: Ica5d219be22ce1f0839596ff654f0402c7c0e555
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/collectors/NumberOfProjectsCollector.java b/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/collectors/NumberOfProjectsCollector.java
index 27c320b..4e41e1d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/collectors/NumberOfProjectsCollector.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/collectors/NumberOfProjectsCollector.java
@@ -14,21 +14,47 @@
package com.googlesource.gerrit.plugins.gitrepometrics.collectors;
-import com.google.gerrit.server.project.ProjectCache;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.flogger.FluentLogger;
+import com.google.gerrit.extensions.api.GerritApi;
+import com.google.gerrit.extensions.restapi.RestApiException;
+import com.google.gerrit.server.util.ManualRequestContext;
+import com.google.gerrit.server.util.OneOffRequestContext;
import com.google.inject.Inject;
import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.gitrepometrics.GitRepoMetricsConfig;
+import java.util.concurrent.TimeUnit;
+@Singleton
public class NumberOfProjectsCollector implements Provider<Long> {
public static final String NUM_PROJECTS = "num-projects";
- private final ProjectCache projectCache;
+ public static final long MIN_NUM_PROJECTS_GRACE_PERIOD_MS = 1000L;
+
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+ private final Supplier<Long> numberOfProjects;
@Inject
- NumberOfProjectsCollector(ProjectCache projectCache) {
- this.projectCache = projectCache;
+ NumberOfProjectsCollector(GerritApi api, OneOffRequestContext ctx, GitRepoMetricsConfig config) {
+ numberOfProjects =
+ Suppliers.memoizeWithExpiration(
+ () -> queryNumberOfProjects(ctx, api),
+ Math.max(MIN_NUM_PROJECTS_GRACE_PERIOD_MS, config.getGracePeriodMs()),
+ TimeUnit.MILLISECONDS);
+ }
+
+ private static long queryNumberOfProjects(OneOffRequestContext ctx, GerritApi api) {
+ try (ManualRequestContext c = ctx.open()) {
+ return api.projects().query().get().size();
+ } catch (RestApiException e) {
+ logger.atWarning().withCause(e).log("Unable to query Gerrit projects list");
+ throw new IllegalStateException(e);
+ }
}
@Override
public Long get() {
- return (long) projectCache.all().size();
+ return numberOfProjects.get();
}
}