Stop creating the entire SchemaVersion chain at runtime
Running Gerrit servers build every Schema_NNN instance at server startup due to the Guice binding for @Current SchemaVersion implicitly linking to everything through the constructors and the Guice injector running in mode PRODUCTION, where all dependencies are resolved immediately at startup. Instead get the binary version off the C constant, which does not require loading all classes. Use a new injector with mode DEVELOPMENT to support lazy loading of older versions only as necessary. Change-Id: I9c62f2603f61bdd58a800b1d03b10c28a0c78773
This commit is contained in:
@@ -1,27 +0,0 @@
|
||||
// Copyright (C) 2009 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.schema;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import com.google.inject.BindingAnnotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
/** Indicates the {@link SchemaVersion} is the current one. */
|
||||
@Retention(RUNTIME)
|
||||
@BindingAnnotation
|
||||
public @interface Current {
|
||||
}
|
@@ -46,23 +46,19 @@ public class SchemaCreator {
|
||||
private final PersonIdent serverUser;
|
||||
private final DataSourceType dataSourceType;
|
||||
|
||||
private final int versionNbr;
|
||||
|
||||
private AccountGroup admin;
|
||||
private AccountGroup batch;
|
||||
|
||||
@Inject
|
||||
public SchemaCreator(SitePaths site,
|
||||
@Current SchemaVersion version,
|
||||
AllProjectsCreator ap,
|
||||
AllUsersCreator auc,
|
||||
@GerritPersonIdent PersonIdent au,
|
||||
DataSourceType dst) {
|
||||
this(site.site_path, version, ap, auc, au, dst);
|
||||
this(site.site_path, ap, auc, au, dst);
|
||||
}
|
||||
|
||||
public SchemaCreator(@SitePath File site,
|
||||
@Current SchemaVersion version,
|
||||
AllProjectsCreator ap,
|
||||
AllUsersCreator auc,
|
||||
@GerritPersonIdent PersonIdent au,
|
||||
@@ -72,7 +68,6 @@ public class SchemaCreator {
|
||||
allUsersCreator = auc;
|
||||
serverUser = au;
|
||||
dataSourceType = dst;
|
||||
versionNbr = version.getVersionNbr();
|
||||
}
|
||||
|
||||
public void create(final ReviewDb db) throws OrmException, IOException,
|
||||
@@ -86,7 +81,7 @@ public class SchemaCreator {
|
||||
}
|
||||
|
||||
final CurrentSchemaVersion sVer = CurrentSchemaVersion.create();
|
||||
sVer.versionNbr = versionNbr;
|
||||
sVer.versionNbr = SchemaVersion.getBinaryVersion();
|
||||
db.schemaVersion().insert(Collections.singleton(sVer));
|
||||
|
||||
initSystemConfig(db);
|
||||
|
@@ -32,8 +32,6 @@ import org.eclipse.jgit.lib.PersonIdent;
|
||||
public class SchemaModule extends FactoryModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(new SchemaVersion.Module());
|
||||
|
||||
bind(PersonIdent.class).annotatedWith(GerritPersonIdent.class)
|
||||
.toProvider(GerritPersonIdentProvider.class);
|
||||
|
||||
|
@@ -17,13 +17,23 @@ package com.google.gerrit.server.schema;
|
||||
import com.google.gerrit.reviewdb.client.CurrentSchemaVersion;
|
||||
import com.google.gerrit.reviewdb.client.SystemConfig;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.GerritPersonIdent;
|
||||
import com.google.gerrit.server.config.AllProjectsName;
|
||||
import com.google.gerrit.server.config.AnonymousCowardName;
|
||||
import com.google.gerrit.server.config.SitePaths;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.gwtorm.server.SchemaFactory;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Stage;
|
||||
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
@@ -37,12 +47,46 @@ public class SchemaUpdater {
|
||||
private final Provider<SchemaVersion> updater;
|
||||
|
||||
@Inject
|
||||
SchemaUpdater(final SchemaFactory<ReviewDb> schema, final SitePaths site,
|
||||
final SchemaCreator creator, @Current final Provider<SchemaVersion> update) {
|
||||
SchemaUpdater(SchemaFactory<ReviewDb> schema,
|
||||
SitePaths site,
|
||||
SchemaCreator creator,
|
||||
Injector parent) {
|
||||
this.schema = schema;
|
||||
this.site = site;
|
||||
this.creator = creator;
|
||||
this.updater = update;
|
||||
this.updater = buildInjector(parent).getProvider(SchemaVersion.class);
|
||||
}
|
||||
|
||||
private static Injector buildInjector(final Injector parent) {
|
||||
// Use DEVELOPMENT mode to allow lazy initialization of the
|
||||
// graph. This avoids touching ancient schema versions that
|
||||
// are behind this installation's current version.
|
||||
return Guice.createInjector(Stage.DEVELOPMENT, new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(SchemaVersion.class).to(SchemaVersion.C);
|
||||
|
||||
for (Key<?> k : new Key<?>[]{
|
||||
Key.get(PersonIdent.class, GerritPersonIdent.class),
|
||||
Key.get(String.class, AnonymousCowardName.class),
|
||||
}) {
|
||||
rebind(parent, k);
|
||||
}
|
||||
|
||||
for (Class<?> c : new Class<?>[] {
|
||||
AllProjectsName.class,
|
||||
AllUsersCreator.class,
|
||||
GitRepositoryManager.class,
|
||||
SitePaths.class,
|
||||
}) {
|
||||
rebind(parent, Key.get(c));
|
||||
}
|
||||
}
|
||||
|
||||
private <T> void rebind(Injector parent, Key<T> c) {
|
||||
bind(c).toProvider(parent.getProvider(c));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void update(final UpdateUI ui) throws OrmException {
|
||||
|
@@ -21,7 +21,6 @@ import com.google.gwtorm.jdbc.JdbcExecutor;
|
||||
import com.google.gwtorm.jdbc.JdbcSchema;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.gwtorm.server.StatementExecutor;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import java.sql.SQLException;
|
||||
@@ -34,11 +33,8 @@ public abstract class SchemaVersion {
|
||||
/** The current schema version. */
|
||||
public static final Class<Schema_103> C = Schema_103.class;
|
||||
|
||||
public static class Module extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(SchemaVersion.class).annotatedWith(Current.class).to(C);
|
||||
}
|
||||
public static int getBinaryVersion() {
|
||||
return guessVersion(C);
|
||||
}
|
||||
|
||||
private final Provider<? extends SchemaVersion> prior;
|
||||
@@ -49,7 +45,7 @@ public abstract class SchemaVersion {
|
||||
this.versionNbr = guessVersion(getClass());
|
||||
}
|
||||
|
||||
public static int guessVersion(Class<?> c) {
|
||||
private static int guessVersion(Class<?> c) {
|
||||
String n = c.getName();
|
||||
n = n.substring(n.lastIndexOf('_') + 1);
|
||||
while (n.startsWith("0"))
|
||||
@@ -57,12 +53,6 @@ public abstract class SchemaVersion {
|
||||
return Integer.parseInt(n);
|
||||
}
|
||||
|
||||
protected SchemaVersion(final Provider<? extends SchemaVersion> prior,
|
||||
final int versionNbr) {
|
||||
this.prior = prior;
|
||||
this.versionNbr = versionNbr;
|
||||
}
|
||||
|
||||
/** @return the {@link CurrentSchemaVersion#versionNbr} this step targets. */
|
||||
public final int getVersionNbr() {
|
||||
return versionNbr;
|
||||
|
@@ -23,7 +23,6 @@ import com.google.gwtorm.server.OrmException;
|
||||
import com.google.gwtorm.server.SchemaFactory;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.ProvisionException;
|
||||
|
||||
/** Validates the current schema version. */
|
||||
@@ -40,16 +39,11 @@ public class SchemaVersionCheck implements LifecycleListener {
|
||||
private final SchemaFactory<ReviewDb> schema;
|
||||
private final SitePaths site;
|
||||
|
||||
@Current
|
||||
private final Provider<SchemaVersion> version;
|
||||
|
||||
@Inject
|
||||
public SchemaVersionCheck(SchemaFactory<ReviewDb> schemaFactory,
|
||||
final SitePaths site,
|
||||
@Current Provider<SchemaVersion> version) {
|
||||
SitePaths site) {
|
||||
this.schema = schemaFactory;
|
||||
this.site = site;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,7 +52,7 @@ public class SchemaVersionCheck implements LifecycleListener {
|
||||
final ReviewDb db = schema.open();
|
||||
try {
|
||||
final CurrentSchemaVersion currentVer = getSchemaVersion(db);
|
||||
final int expectedVer = version.get().getVersionNbr();
|
||||
final int expectedVer = SchemaVersion.getBinaryVersion();
|
||||
|
||||
if (currentVer == null) {
|
||||
throw new ProvisionException("Schema not yet initialized."
|
||||
|
@@ -74,7 +74,6 @@ public class SchemaUpdaterTest {
|
||||
protected void configure() {
|
||||
bind(new TypeLiteral<SchemaFactory<ReviewDb>>() {}).toInstance(db);
|
||||
bind(SitePaths.class).toInstance(paths);
|
||||
install(new SchemaVersion.Module());
|
||||
|
||||
Config cfg = new Config();
|
||||
cfg.setString("user", null, "name", "Gerrit Code Review");
|
||||
|
@@ -67,7 +67,6 @@ public class InMemoryDatabase implements SchemaFactory<ReviewDb> {
|
||||
}
|
||||
}
|
||||
|
||||
private final SchemaVersion schemaVersion;
|
||||
private final SchemaCreator schemaCreator;
|
||||
|
||||
private Connection openHandle;
|
||||
@@ -75,9 +74,7 @@ public class InMemoryDatabase implements SchemaFactory<ReviewDb> {
|
||||
private boolean created;
|
||||
|
||||
@Inject
|
||||
InMemoryDatabase(SchemaVersion schemaVersion,
|
||||
SchemaCreator schemaCreator) throws OrmException {
|
||||
this.schemaVersion = schemaVersion;
|
||||
InMemoryDatabase(SchemaCreator schemaCreator) throws OrmException {
|
||||
this.schemaCreator = schemaCreator;
|
||||
|
||||
try {
|
||||
@@ -161,6 +158,6 @@ public class InMemoryDatabase implements SchemaFactory<ReviewDb> {
|
||||
|
||||
public void assertSchemaVersion() throws OrmException {
|
||||
final CurrentSchemaVersion act = getSchemaVersion();
|
||||
assertEquals(schemaVersion.getVersionNbr(), act.versionNbr);
|
||||
assertEquals(SchemaVersion.getBinaryVersion(), act.versionNbr);
|
||||
}
|
||||
}
|
||||
|
@@ -48,10 +48,8 @@ import com.google.gerrit.server.index.ChangeSchemas;
|
||||
import com.google.gerrit.server.index.IndexModule.IndexType;
|
||||
import com.google.gerrit.server.mail.SignedTokenEmailTokenVerifier;
|
||||
import com.google.gerrit.server.mail.SmtpEmailSender;
|
||||
import com.google.gerrit.server.schema.Current;
|
||||
import com.google.gerrit.server.schema.DataSourceType;
|
||||
import com.google.gerrit.server.schema.SchemaCreator;
|
||||
import com.google.gerrit.server.schema.SchemaVersion;
|
||||
import com.google.gerrit.server.securestore.DefaultSecureStore;
|
||||
import com.google.gerrit.server.securestore.SecureStore;
|
||||
import com.google.gerrit.server.ssh.NoSshKeyCache;
|
||||
@@ -127,8 +125,6 @@ public class InMemoryModule extends FactoryModule {
|
||||
|
||||
bindScope(RequestScoped.class, PerThreadRequestScope.REQUEST);
|
||||
|
||||
install(new SchemaVersion.Module());
|
||||
|
||||
bind(File.class).annotatedWith(SitePath.class).toInstance(new File("."));
|
||||
bind(Config.class).annotatedWith(GerritServerConfig.class).toInstance(cfg);
|
||||
bind(SocketAddress.class).annotatedWith(RemotePeer.class).toInstance(
|
||||
@@ -197,9 +193,9 @@ public class InMemoryModule extends FactoryModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
InMemoryDatabase getInMemoryDatabase(@Current SchemaVersion schemaVersion,
|
||||
SchemaCreator schemaCreator) throws OrmException {
|
||||
return new InMemoryDatabase(schemaVersion, schemaCreator);
|
||||
InMemoryDatabase getInMemoryDatabase(SchemaCreator schemaCreator)
|
||||
throws OrmException {
|
||||
return new InMemoryDatabase(schemaCreator);
|
||||
}
|
||||
|
||||
private Module luceneIndexModule() {
|
||||
|
Reference in New Issue
Block a user