Export ServerInformation to extensions and plugins
Plugins can take this value by injection and learn the current server state during their own LifecycleListener. This enables a plugin to determine if it is loading as part of server startup, or because it was dynamically installed or reloaded by an administrator. Change-Id: Iac57e039ed9f9f3ecaf2f384c5a3c6a66223f5e1
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
// 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.extensions.systemstatus;
|
||||
|
||||
/** Exports current server information to an extension. */
|
||||
public interface ServerInformation {
|
||||
/** Current state of the server. */
|
||||
public enum State {
|
||||
/**
|
||||
* The server is starting up, and network connections are not yet being
|
||||
* accepted. Plugins or extensions starting during this time are starting
|
||||
* for the first time in this process.
|
||||
*/
|
||||
STARTUP,
|
||||
|
||||
/**
|
||||
* The server is running and handling requests. Plugins starting during this
|
||||
* state may be reloading, or being installed into a running system.
|
||||
*/
|
||||
RUNNING,
|
||||
|
||||
/**
|
||||
* The server is attempting a graceful halt of operations and will exit (or
|
||||
* be killed by the operating system) soon.
|
||||
*/
|
||||
SHUTDOWN;
|
||||
}
|
||||
|
||||
State getState();
|
||||
}
|
@@ -19,6 +19,7 @@ import com.google.common.collect.Lists;
|
||||
import com.google.gerrit.extensions.annotations.PluginName;
|
||||
import com.google.gerrit.extensions.registration.RegistrationHandle;
|
||||
import com.google.gerrit.extensions.registration.ReloadableRegistrationHandle;
|
||||
import com.google.gerrit.extensions.systemstatus.ServerInformation;
|
||||
import com.google.gerrit.lifecycle.LifecycleListener;
|
||||
import com.google.gerrit.lifecycle.LifecycleManager;
|
||||
import com.google.inject.AbstractModule;
|
||||
@@ -165,16 +166,24 @@ public class Plugin {
|
||||
}
|
||||
|
||||
private Injector newRootInjector(PluginGuiceEnvironment env) {
|
||||
return Guice.createInjector(
|
||||
env.getSysModule(),
|
||||
new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(String.class)
|
||||
.annotatedWith(PluginName.class)
|
||||
.toInstance(name);
|
||||
}
|
||||
});
|
||||
List<Module> modules = Lists.newArrayListWithCapacity(4);
|
||||
modules.add(env.getSysModule());
|
||||
final ServerInformation srvInfo = env.getServerInformation();
|
||||
modules.add(new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(ServerInformation.class).toInstance(srvInfo);
|
||||
}
|
||||
});
|
||||
modules.add(new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(String.class)
|
||||
.annotatedWith(PluginName.class)
|
||||
.toInstance(name);
|
||||
}
|
||||
});
|
||||
return Guice.createInjector(modules);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
|
@@ -24,6 +24,7 @@ import com.google.gerrit.extensions.registration.DynamicSet;
|
||||
import com.google.gerrit.extensions.registration.PrivateInternals_DynamicMapImpl;
|
||||
import com.google.gerrit.extensions.registration.RegistrationHandle;
|
||||
import com.google.gerrit.extensions.registration.ReloadableRegistrationHandle;
|
||||
import com.google.gerrit.extensions.systemstatus.ServerInformation;
|
||||
import com.google.gerrit.lifecycle.LifecycleListener;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Binding;
|
||||
@@ -56,6 +57,7 @@ import javax.inject.Inject;
|
||||
@Singleton
|
||||
public class PluginGuiceEnvironment {
|
||||
private final Injector sysInjector;
|
||||
private final ServerInformation srvInfo;
|
||||
private final CopyConfigModule copyConfigModule;
|
||||
private final List<StartPluginListener> onStart;
|
||||
private final List<ReloadPluginListener> onReload;
|
||||
@@ -76,8 +78,12 @@ public class PluginGuiceEnvironment {
|
||||
private Map<TypeLiteral<?>, DynamicMap<?>> httpMaps;
|
||||
|
||||
@Inject
|
||||
PluginGuiceEnvironment(Injector sysInjector, CopyConfigModule ccm) {
|
||||
PluginGuiceEnvironment(
|
||||
Injector sysInjector,
|
||||
ServerInformation srvInfo,
|
||||
CopyConfigModule ccm) {
|
||||
this.sysInjector = sysInjector;
|
||||
this.srvInfo = srvInfo;
|
||||
this.copyConfigModule = ccm;
|
||||
|
||||
onStart = new CopyOnWriteArrayList<StartPluginListener>();
|
||||
@@ -90,6 +96,10 @@ public class PluginGuiceEnvironment {
|
||||
sysMaps = dynamicMapsOf(sysInjector);
|
||||
}
|
||||
|
||||
ServerInformation getServerInformation() {
|
||||
return srvInfo;
|
||||
}
|
||||
|
||||
boolean hasDynamicSet(TypeLiteral<?> type) {
|
||||
return sysSets.containsKey(type)
|
||||
|| (sshSets != null && sshSets.containsKey(type))
|
||||
|
@@ -17,6 +17,7 @@ package com.google.gerrit.server.plugins;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gerrit.extensions.systemstatus.ServerInformation;
|
||||
import com.google.gerrit.lifecycle.LifecycleListener;
|
||||
import com.google.gerrit.server.config.ConfigUtil;
|
||||
import com.google.gerrit.server.config.GerritServerConfig;
|
||||
@@ -59,6 +60,7 @@ public class PluginLoader implements LifecycleListener {
|
||||
private final File pluginsDir;
|
||||
private final File tmpDir;
|
||||
private final PluginGuiceEnvironment env;
|
||||
private final ServerInformationImpl srvInfoImpl;
|
||||
private final ConcurrentMap<String, Plugin> running;
|
||||
private final Map<String, FileSnapshot> broken;
|
||||
private final ReferenceQueue<ClassLoader> cleanupQueue;
|
||||
@@ -68,10 +70,12 @@ public class PluginLoader implements LifecycleListener {
|
||||
@Inject
|
||||
public PluginLoader(SitePaths sitePaths,
|
||||
PluginGuiceEnvironment pe,
|
||||
ServerInformationImpl sii,
|
||||
@GerritServerConfig Config cfg) {
|
||||
pluginsDir = sitePaths.plugins_dir;
|
||||
tmpDir = sitePaths.tmp_dir;
|
||||
env = pe;
|
||||
srvInfoImpl = sii;
|
||||
running = Maps.newConcurrentMap();
|
||||
broken = Maps.newHashMap();
|
||||
cleanupQueue = new ReferenceQueue<ClassLoader>();
|
||||
@@ -184,7 +188,9 @@ public class PluginLoader implements LifecycleListener {
|
||||
@Override
|
||||
public synchronized void start() {
|
||||
log.info("Loading plugins from " + pluginsDir.getAbsolutePath());
|
||||
srvInfoImpl.state = ServerInformation.State.STARTUP;
|
||||
rescan(false);
|
||||
srvInfoImpl.state = ServerInformation.State.RUNNING;
|
||||
if (scanner != null) {
|
||||
scanner.start();
|
||||
}
|
||||
@@ -195,6 +201,7 @@ public class PluginLoader implements LifecycleListener {
|
||||
if (scanner != null) {
|
||||
scanner.end();
|
||||
}
|
||||
srvInfoImpl.state = ServerInformation.State.SHUTDOWN;
|
||||
synchronized (this) {
|
||||
boolean clean = !running.isEmpty();
|
||||
for (Plugin p : running.values()) {
|
||||
|
@@ -14,11 +14,15 @@
|
||||
|
||||
package com.google.gerrit.server.plugins;
|
||||
|
||||
import com.google.gerrit.extensions.systemstatus.ServerInformation;
|
||||
import com.google.gerrit.lifecycle.LifecycleModule;
|
||||
|
||||
public class PluginModule extends LifecycleModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(ServerInformationImpl.class);
|
||||
bind(ServerInformation.class).to(ServerInformationImpl.class);
|
||||
|
||||
bind(PluginGuiceEnvironment.class);
|
||||
bind(PluginLoader.class);
|
||||
bind(CopyConfigModule.class);
|
||||
|
@@ -0,0 +1,28 @@
|
||||
// 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.plugins;
|
||||
|
||||
import com.google.gerrit.extensions.systemstatus.ServerInformation;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
@Singleton
|
||||
class ServerInformationImpl implements ServerInformation {
|
||||
volatile State state = State.STARTUP;
|
||||
|
||||
@Override
|
||||
public State getState() {
|
||||
return state;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user