Merge "Caching of changes"
This commit is contained in:
commit
ed0488c79b
@ -476,6 +476,15 @@ for the client to use as potential delta bases. Push over smart HTTP
|
||||
requires two HTTP requests, and this cache tries to carry state from
|
||||
the first request into the second to ensure it can complete.
|
||||
|
||||
cache `"changes"`::
|
||||
+
|
||||
Each item caches all changes tied to one project. Default size
|
||||
is 1024, which means all changes for up to 1024 projects can be held
|
||||
in the cache. This cache should probably be disabled in a multi-master
|
||||
setup where change updates are not communicated between servers. The
|
||||
cache should be flushed whenever the database changes table is modified
|
||||
outside of gerrit.
|
||||
|
||||
cache `"diff"`::
|
||||
+
|
||||
Each item caches the differences between two commits, at both the
|
||||
|
@ -23,6 +23,7 @@ import com.google.gerrit.server.AnonymousUser;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.cache.CacheModule;
|
||||
import com.google.gerrit.server.git.AsyncReceiveCommits;
|
||||
import com.google.gerrit.server.git.ChangeCache;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.git.ReceiveCommits;
|
||||
import com.google.gerrit.server.git.TagCache;
|
||||
@ -198,11 +199,13 @@ public class GitOverHttpServlet extends GitServlet {
|
||||
static class UploadFilter implements Filter {
|
||||
private final Provider<ReviewDb> db;
|
||||
private final TagCache tagCache;
|
||||
private final ChangeCache changeCache;
|
||||
|
||||
@Inject
|
||||
UploadFilter(Provider<ReviewDb> db, TagCache tagCache) {
|
||||
UploadFilter(Provider<ReviewDb> db, TagCache tagCache, ChangeCache changeCache) {
|
||||
this.db = db;
|
||||
this.tagCache = tagCache;
|
||||
this.changeCache = changeCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -221,7 +224,7 @@ public class GitOverHttpServlet extends GitServlet {
|
||||
}
|
||||
|
||||
if (!pc.allRefsAreVisible()) {
|
||||
up.setAdvertiseRefsHook(new VisibleRefFilter(tagCache, repo, pc, db.get(), true));
|
||||
up.setAdvertiseRefsHook(new VisibleRefFilter(tagCache, changeCache, repo, pc, db.get(), true));
|
||||
}
|
||||
|
||||
next.doFilter(request, response);
|
||||
|
@ -52,6 +52,7 @@ import com.google.gerrit.server.auth.ldap.LdapModule;
|
||||
import com.google.gerrit.server.cache.CacheRemovalListener;
|
||||
import com.google.gerrit.server.events.EventFactory;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.git.ChangeCache;
|
||||
import com.google.gerrit.server.git.ChangeMergeQueue;
|
||||
import com.google.gerrit.server.git.GitModule;
|
||||
import com.google.gerrit.server.git.MergeQueue;
|
||||
@ -125,6 +126,8 @@ public class GerritGlobalModule extends FactoryModule {
|
||||
install(ProjectCacheImpl.module());
|
||||
install(SectionSortCache.module());
|
||||
install(TagCache.module());
|
||||
install(ChangeCache.module());
|
||||
|
||||
install(new AccessControlModule());
|
||||
install(new GitModule());
|
||||
install(new PrologModule());
|
||||
@ -176,6 +179,7 @@ public class GerritGlobalModule extends FactoryModule {
|
||||
DynamicSet.setOf(binder(), CacheRemovalListener.class);
|
||||
DynamicSet.setOf(binder(), GitReferenceUpdatedListener.class);
|
||||
DynamicSet.setOf(binder(), NewProjectCreatedListener.class);
|
||||
DynamicSet.bind(binder(), GitReferenceUpdatedListener.class).to(ChangeCache.class);
|
||||
|
||||
bind(AnonymousUser.class);
|
||||
}
|
||||
|
@ -0,0 +1,101 @@
|
||||
// Copyright (C) 2012 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.package com.google.gerrit.server.git;
|
||||
|
||||
package com.google.gerrit.server.git;
|
||||
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.cache.CacheModule;
|
||||
import com.google.gwtorm.server.SchemaFactory;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.name.Named;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
@Singleton
|
||||
public class ChangeCache implements GitReferenceUpdatedListener {
|
||||
private static final Logger log =
|
||||
LoggerFactory.getLogger(ChangeCache.class);
|
||||
private static final String ID_CACHE = "changes";
|
||||
|
||||
public static Module module() {
|
||||
return new CacheModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
cache(ID_CACHE,
|
||||
Project.NameKey.class,
|
||||
new TypeLiteral<List<Change>>() {})
|
||||
.maximumWeight(1024)
|
||||
.loader(Loader.class);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private final LoadingCache<Project.NameKey, List<Change>> cache;
|
||||
|
||||
@Inject
|
||||
ChangeCache(@Named(ID_CACHE) LoadingCache<Project.NameKey, List<Change>> cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
List<Change> get(Project.NameKey name) {
|
||||
try {
|
||||
return cache.get(name);
|
||||
} catch (ExecutionException e) {
|
||||
log.warn("Cannot fetch changes for " + name, e);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGitReferenceUpdated(GitReferenceUpdatedListener.Event event) {
|
||||
for (GitReferenceUpdatedListener.Update u : event.getUpdates()) {
|
||||
if (u.getRefName().startsWith("refs/changes/")) {
|
||||
cache.invalidate(new Project.NameKey(event.getProjectName()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class Loader extends CacheLoader<Project.NameKey, List<Change>> {
|
||||
private final SchemaFactory<ReviewDb> schema;
|
||||
|
||||
@Inject
|
||||
Loader(SchemaFactory<ReviewDb> schema) {
|
||||
this.schema = schema;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Change> load(Project.NameKey key) throws Exception {
|
||||
final ReviewDb db = schema.open();
|
||||
try {
|
||||
return Collections.unmodifiableList(db.changes().byProject(key).toList());
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -252,6 +252,7 @@ public class ReceiveCommits {
|
||||
private final PersonIdent gerritIdent;
|
||||
private final TrackingFooters trackingFooters;
|
||||
private final TagCache tagCache;
|
||||
private final ChangeCache changeCache;
|
||||
private final WorkQueue workQueue;
|
||||
private final ListeningExecutorService changeUpdateExector;
|
||||
private final RequestScopePropagator requestScopePropagator;
|
||||
@ -302,6 +303,7 @@ public class ReceiveCommits {
|
||||
final ProjectCache projectCache,
|
||||
final GitRepositoryManager repoManager,
|
||||
final TagCache tagCache,
|
||||
final ChangeCache changeCache,
|
||||
@CanonicalWebUrl @Nullable final String canonicalWebUrl,
|
||||
@GerritPersonIdent final PersonIdent gerritIdent,
|
||||
final TrackingFooters trackingFooters,
|
||||
@ -330,6 +332,7 @@ public class ReceiveCommits {
|
||||
this.gerritIdent = gerritIdent;
|
||||
this.trackingFooters = trackingFooters;
|
||||
this.tagCache = tagCache;
|
||||
this.changeCache = changeCache;
|
||||
this.workQueue = workQueue;
|
||||
this.changeUpdateExector = changeUpdateExector;
|
||||
this.requestScopePropagator = requestScopePropagator;
|
||||
@ -352,7 +355,7 @@ public class ReceiveCommits {
|
||||
|
||||
if (!projectControl.allRefsAreVisible()) {
|
||||
rp.setCheckReferencedObjectsAreReachable(true);
|
||||
rp.setAdvertiseRefsHook(new VisibleRefFilter(tagCache, repo, projectControl, db, false));
|
||||
rp.setAdvertiseRefsHook(new VisibleRefFilter(tagCache, changeCache, repo, projectControl, db, false));
|
||||
}
|
||||
List<AdvertiseRefsHook> advHooks = new ArrayList<AdvertiseRefsHook>(2);
|
||||
advHooks.add(rp.getAdvertiseRefsHook());
|
||||
|
@ -22,7 +22,6 @@ import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.project.ProjectControl;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
@ -44,16 +43,19 @@ public class VisibleRefFilter extends AbstractAdvertiseRefsHook {
|
||||
LoggerFactory.getLogger(VisibleRefFilter.class);
|
||||
|
||||
private final TagCache tagCache;
|
||||
private final ChangeCache changeCache;
|
||||
private final Repository db;
|
||||
private final Project.NameKey projectName;
|
||||
private final ProjectControl projectCtl;
|
||||
private final ReviewDb reviewDb;
|
||||
private final boolean showChanges;
|
||||
|
||||
public VisibleRefFilter(final TagCache tagCache, final Repository db,
|
||||
public VisibleRefFilter(final TagCache tagCache, final ChangeCache changeCache,
|
||||
final Repository db,
|
||||
final ProjectControl projectControl, final ReviewDb reviewDb,
|
||||
final boolean showChanges) {
|
||||
this.tagCache = tagCache;
|
||||
this.changeCache = changeCache;
|
||||
this.db = db;
|
||||
this.projectName = projectControl.getProject().getNameKey();
|
||||
this.projectCtl = projectControl;
|
||||
@ -133,7 +135,7 @@ public class VisibleRefFilter extends AbstractAdvertiseRefsHook {
|
||||
final Project project = projectCtl.getProject();
|
||||
try {
|
||||
final Set<Change.Id> visibleChanges = new HashSet<Change.Id>();
|
||||
for (Change change : reviewDb.changes().byProject(project.getNameKey())) {
|
||||
for (Change change : changeCache.get(project.getNameKey())) {
|
||||
if (projectCtl.controlFor(change).isVisible(reviewDb)) {
|
||||
visibleChanges.add(change.getId());
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
package com.google.gerrit.sshd.commands;
|
||||
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.git.ChangeCache;
|
||||
import com.google.gerrit.server.git.TagCache;
|
||||
import com.google.gerrit.server.git.TransferConfig;
|
||||
import com.google.gerrit.server.git.VisibleRefFilter;
|
||||
@ -37,6 +38,9 @@ final class Upload extends AbstractGitCommand {
|
||||
@Inject
|
||||
private TagCache tagCache;
|
||||
|
||||
@Inject
|
||||
private ChangeCache changeCache;
|
||||
|
||||
@Override
|
||||
protected void runImpl() throws IOException, Failure {
|
||||
if (!projectControl.canRunUploadPack()) {
|
||||
@ -45,7 +49,7 @@ final class Upload extends AbstractGitCommand {
|
||||
|
||||
final UploadPack up = new UploadPack(repo);
|
||||
if (!projectControl.allRefsAreVisible()) {
|
||||
up.setAdvertiseRefsHook(new VisibleRefFilter(tagCache, repo,
|
||||
up.setAdvertiseRefsHook(new VisibleRefFilter(tagCache, changeCache, repo,
|
||||
projectControl, db.get(), true));
|
||||
}
|
||||
up.setPackConfig(config.getPackConfig());
|
||||
|
Loading…
Reference in New Issue
Block a user