Permalink
Browse files

AS7-4934 Provide a server-wide shared thread pool for possibly blocki…

…ng tasks; particularly lifecycle.

Use said pool in most places that are currently creating their own one-off pools.
  • Loading branch information...
1 parent fa20a06 commit 28b4a21f20697fd2b2f410ccb877247678c5d9a8 @bstansberry bstansberry committed Jun 1, 2012
@@ -50,6 +50,7 @@ protected AsynchronousService() {
protected AsynchronousService(boolean startAsynchronously, boolean stopAsynchronously) {
this.startAsynchronously = startAsynchronously;
this.stopAsynchronously = stopAsynchronously;
+ // TODO Use org.jboss.as.server.Services#addServerExecutorDependency to inject a shared executor
final ThreadFactory factory = new JBossThreadFactory(new ThreadGroup(String.format("%s lifecycle", this.getClass().getSimpleName())),
Boolean.FALSE, null, "%G - %t", null, null, AccessController.getContext());
this. executor = Executors.newCachedThreadPool(factory);
@@ -107,9 +107,11 @@ protected void removeRuntimeServices(OperationContext context, ModelNode operati
protected ServiceController<ProtocolDefaults> installProtocolDefaultsService(ServiceTarget target,
ServiceVerificationHandler verificationHandler) {
+ final ProtocolDefaultsService service = new ProtocolDefaultsService();
ServiceBuilder<ProtocolDefaults> protocolDefaultsBuilder =
- target.addService(ProtocolDefaultsService.SERVICE_NAME, new ProtocolDefaultsService())
+ target.addService(ProtocolDefaultsService.SERVICE_NAME, service)
.setInitialMode(ServiceController.Mode.ON_DEMAND) ;
+ org.jboss.as.server.Services.addServerExecutorDependency(protocolDefaultsBuilder, service.getExecutorInjector(), false);
return protocolDefaultsBuilder.install() ;
}
@@ -28,14 +28,17 @@
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.jboss.as.clustering.jgroups.ProtocolDefaults;
+import org.jboss.msc.inject.Injector;
import org.jboss.msc.service.Service;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.StartContext;
import org.jboss.msc.service.StartException;
import org.jboss.msc.service.StopContext;
+import org.jboss.msc.value.InjectedValue;
import org.jgroups.conf.ProtocolStackConfigurator;
import org.jgroups.conf.XmlConfigurator;
@@ -52,11 +55,12 @@
private static final String DEFAULTS = "jgroups-defaults.xml";
- private final Executor executor = Executors.newCachedThreadPool();
+ private final InjectedValue<ExecutorService> executorInjector = new InjectedValue<ExecutorService>();
private final String resource;
private volatile ProtocolDefaults defaults;
public ProtocolDefaultsService() {
+
this(DEFAULTS);
}
@@ -79,6 +83,7 @@ public ProtocolDefaults getValue() {
*/
@Override
public void start(final StartContext context) throws StartException {
+ final ExecutorService executor = executorInjector.getValue();
Runnable task = new Runnable() {
@Override
public void run() {
@@ -91,7 +96,7 @@ public void run() {
}
};
context.asynchronous();
- this.executor.execute(task);
+ executor.execute(task);
}
void start() throws StartException {
@@ -103,6 +108,10 @@ void start() throws StartException {
ProtocolDefaultsService.this.defaults = defaults;
}
+ InjectedValue<ExecutorService> getExecutorInjector() {
+ return executorInjector;
+ }
+
private static ProtocolStackConfigurator load(String resource) throws StartException {
URL url = find(resource, JGroupsExtension.class.getClassLoader());
ROOT_LOGGER.debugf("Loading JGroups protocol defaults from %s", url.toString());
@@ -184,7 +184,7 @@ protected void componentInstanceCreated(final BasicComponentInstance basicCompon
* {@link #constructComponentInstance(ManagedReference, boolean, InterceptorFactoryContext)}.
* <p/>
*
- * @return
+ * @return the component instance
*/
protected BasicComponentInstance instantiateComponentInstance(final AtomicReference<ManagedReference> instanceReference, final Interceptor preDestroyInterceptor, final Map<Method, Interceptor> methodInterceptors, final InterceptorFactoryContext context) {
// create and return the component instance
@@ -238,6 +238,8 @@ public void stop(final StopContext stopContext) {
//TODO: only run this if there is no instances
//TODO: trigger destruction of all component instances
//TODO: this has lots of potential for race conditions unless we are careful
+ //TODO: using stopContext.asynchronous() and then executing synchronously is pointless.
+ // Use org.jboss.as.server.Services#addServerExecutorDependency to inject an executor to do this async
stopContext.complete();
}
}
@@ -140,6 +140,7 @@ public void execute(DeploymentProcessorTarget processorTarget) {
CorbaORBService orbService = new CorbaORBService(props);
final ServiceBuilder<ORB> builder = context.getServiceTarget().addService(
CorbaORBService.SERVICE_NAME, orbService);
+ org.jboss.as.server.Services.addServerExecutorDependency(builder, orbService.getExecutorInjector(), false);
// if a security domain has been specified, add a dependency to the domain service.
String securityDomain = props.getProperty(JacORBSubsystemConstants.SECURITY_SECURITY_DOMAIN);
@@ -26,6 +26,7 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Properties;
+import java.util.concurrent.ExecutorService;
import org.jboss.as.jacorb.JacORBLogger;
import org.jboss.as.jacorb.JacORBSubsystemConstants;
@@ -57,6 +58,8 @@
private static final Properties properties = new Properties();
+ private final InjectedValue<ExecutorService> executorInjector = new InjectedValue<ExecutorService>();
+
private final InjectedValue<SocketBinding> jacORBSocketBindingInjector = new InjectedValue<SocketBinding>();
private final InjectedValue<SocketBinding> jacORBSSLSocketBindingInjector = new InjectedValue<SocketBinding>();
@@ -147,8 +150,8 @@ public void stop(StopContext context) {
JacORBLogger.ROOT_LOGGER.debugServiceStop(context.getController().getName().getCanonicalName());
// stop the ORB asynchronously.
context.asynchronous();
- Thread destroyThread = SecurityActions.createThread(new ORBDestroyer(this.orb, context), "ORB Destroy Thread");
- destroyThread.start();
+ ORBDestroyer destroyer = new ORBDestroyer(this.orb, context);
+ executorInjector.getValue().execute(destroyer);
}
@Override
@@ -182,6 +185,18 @@ public ORB getValue() throws IllegalStateException, IllegalArgumentException {
/**
* <p>
+ * Obtains a reference to the executor service injector. This injector is used to inject a
+ * {@link ExecutorService} for use in blocking tasks during startup or shutdown.
+ * </p>
+ *
+ * @return a reference to the {@code Injector<Executor>} used to inject the executor service.
+ */
+ public InjectedValue<ExecutorService> getExecutorInjector() {
+ return executorInjector;
+ }
+
+ /**
+ * <p>
* Gets the value of the specified ORB property. All ORB properties can be queried using this method. This includes
* the properties that have been explicitly set by this service prior to creating the ORB and all JacORB properties
* that have been specified in the JacORB subsystem configuration.
@@ -289,7 +289,6 @@ public void execute(OperationContext context, ModelNode operation) throws Operat
newControllers.add(hqServerServiceController);
newControllers.add(JMSService.addService(serviceTarget, hqServiceName, verificationHandler));
- newControllers.add(HornetQStartupPoolService.addService(serviceTarget, hqServiceName, verificationHandler));
context.completeStep();
}
@@ -1,70 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2012, Red Hat, Inc., and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.as.messaging;
-
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import org.hornetq.core.server.HornetQServer;
-import org.jboss.as.messaging.jms.JMSServices;
-import org.jboss.msc.service.Service;
-import org.jboss.msc.service.ServiceController;
-import org.jboss.msc.service.ServiceListener;
-import org.jboss.msc.service.ServiceName;
-import org.jboss.msc.service.ServiceTarget;
-import org.jboss.msc.service.StartContext;
-import org.jboss.msc.service.StartException;
-import org.jboss.msc.service.StopContext;
-
-/**
- * Pool used to execute potentially blocking startup tasks.
- *
- * @author Jason T. Greene
- */
-public class HornetQStartupPoolService implements Service<Executor>{
- private volatile ExecutorService executor;
-
- public static ServiceController<?> addService(final ServiceTarget target, ServiceName hqServiceName, final ServiceListener<Object>... listeners) {
- final HornetQStartupPoolService service = new HornetQStartupPoolService();
- return target.addService(MessagingServices.getHornetQStartupPoolServiceName(hqServiceName), service)
- .addListener(listeners)
- .setInitialMode(ServiceController.Mode.ACTIVE)
- .install();
- }
-
- @Override
- public void start(StartContext context) throws StartException {
- executor = Executors.newCachedThreadPool();
- }
-
- @Override
- public synchronized void stop(StopContext context) {
- executor.shutdown();
- executor = null;
- }
-
- @Override
- public Executor getValue() throws IllegalStateException, IllegalArgumentException {
- return executor;
- }
-}
@@ -65,10 +65,6 @@ public static ServiceName getHornetQServiceName(String serverName) {
return JBOSS_MESSAGING.append(serverName);
}
- public static ServiceName getHornetQStartupPoolServiceName(ServiceName hqServiceName) {
- return hqServiceName.append(STARTUP_POOL);
- }
-
public static ServiceName getQueueBaseServiceName(ServiceName hornetqServiceName) {
return hornetqServiceName.append(CORE_QUEUE_BASE);
}
@@ -25,7 +25,6 @@
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.Executor;
import org.hornetq.api.core.client.HornetQClient;
import org.hornetq.api.jms.JMSFactoryType;
@@ -43,6 +42,7 @@
import org.jboss.as.messaging.MessagingMessages;
import org.jboss.as.messaging.MessagingServices;
import org.jboss.dmr.ModelNode;
+import org.jboss.msc.service.ServiceBuilder;
import org.jboss.msc.service.ServiceController;
import org.jboss.msc.service.ServiceController.Mode;
import org.jboss.msc.service.ServiceName;
@@ -122,12 +122,12 @@ protected void performRuntime(OperationContext context, ModelNode operation, Mod
final ConnectionFactoryConfiguration configuration = createConfiguration(context, name, model);
final ConnectionFactoryService service = new ConnectionFactoryService(configuration);
final ServiceName serviceName = JMSServices.getConnectionFactoryBaseServiceName(hqServiceName).append(name);
- newControllers.add(context.getServiceTarget().addService(serviceName, service)
+ ServiceBuilder<?> serviceBuilder = context.getServiceTarget().addService(serviceName, service)
.addDependency(JMSServices.getJmsManagerBaseServiceName(hqServiceName), JMSServerManager.class, service.getJmsServer())
- .addDependency(MessagingServices.getHornetQStartupPoolServiceName(hqServiceName), Executor.class, service.getExecutorInjector())
.addListener(verificationHandler)
- .setInitialMode(Mode.ACTIVE)
- .install());
+ .setInitialMode(Mode.ACTIVE);
+ org.jboss.as.server.Services.addServerExecutorDependency(serviceBuilder, service.getExecutorInjector(), false);
+ newControllers.add(serviceBuilder.install());
}
static ConnectionFactoryConfiguration createConfiguration(final OperationContext context, final String name, final ModelNode model) throws OperationFailedException {
@@ -24,7 +24,6 @@
import org.hornetq.jms.server.JMSServerManager;
import org.hornetq.jms.server.config.ConnectionFactoryConfiguration;
-import org.jboss.as.naming.WritableServiceBasedNamingStore;
import org.jboss.msc.service.Service;
import org.jboss.msc.service.StartContext;
import org.jboss.msc.service.StartException;
@@ -34,10 +33,10 @@
import static org.jboss.as.messaging.MessagingLogger.MESSAGING_LOGGER;
import static org.jboss.as.messaging.MessagingMessages.MESSAGES;
-import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
/**
- * {@code Service} responsible for creating and destroying a {@link javax.jms.ConnectionFactory}.
+ * {@code Service} responsible for creating and destroying a {@code javax.jms.ConnectionFactory}.
*
* @author Emanuel Muckenhuber
*/
@@ -46,7 +45,7 @@
private final String name;
private final ConnectionFactoryConfiguration configuration;
private final InjectedValue<JMSServerManager> jmsServer = new InjectedValue<JMSServerManager>();
- private final InjectedValue<Executor> executorInjector = new InjectedValue<Executor>();
+ private final InjectedValue<ExecutorService> executorInjector = new InjectedValue<ExecutorService>();
public ConnectionFactoryService(final ConnectionFactoryConfiguration configuration) {
name = configuration.getName();
@@ -102,7 +101,8 @@ public Void getValue() throws IllegalStateException {
return jmsServer;
}
- public InjectedValue<Executor> getExecutorInjector() {
+
+ public InjectedValue<ExecutorService> getExecutorInjector() {
return executorInjector;
}
}
@@ -24,7 +24,6 @@
import java.util.List;
import java.util.Locale;
-import java.util.concurrent.Executor;
import org.hornetq.jms.server.JMSServerManager;
import org.jboss.as.controller.AbstractAddStepHandler;
@@ -108,16 +107,15 @@ public void installServices(final ServiceVerificationHandler verificationHandler
final JMSQueueService service = new JMSQueueService(name, selector, durable, jndiBindings);
final ServiceName serviceName = JMSServices.getJmsQueueBaseServiceName(hqServiceName).append(name);
- final ServiceBuilder<Void> serviceBuilder = serviceTarget.addService(serviceName, service);
+ final ServiceBuilder<Void> serviceBuilder = serviceTarget.addService(serviceName, service)
+ .addDependency(JMSServices.getJmsManagerBaseServiceName(hqServiceName), JMSServerManager.class, service.getJmsServer())
+ .setInitialMode(Mode.ACTIVE);
+ org.jboss.as.server.Services.addServerExecutorDependency(serviceBuilder, service.getExecutorInjector(), false);
if (verificationHandler != null) {
serviceBuilder.addListener(verificationHandler);
}
- final ServiceController<Void> controller = serviceBuilder
- .addDependency(JMSServices.getJmsManagerBaseServiceName(hqServiceName), JMSServerManager.class, service.getJmsServer())
- .addDependency(MessagingServices.getHornetQStartupPoolServiceName(hqServiceName), Executor.class, service.getExecutorInjector())
- .setInitialMode(Mode.ACTIVE)
- .install();
+ final ServiceController<Void> controller = serviceBuilder.install();
if (newControllers != null) {
newControllers.add(controller);
}
@@ -33,7 +33,7 @@
import static org.jboss.as.messaging.MessagingLogger.MESSAGING_LOGGER;
import static org.jboss.as.messaging.MessagingMessages.MESSAGES;
-import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
/**
* Service responsible for creating and destroying a {@code javax.jms.Queue}.
@@ -43,7 +43,7 @@
public class JMSQueueService implements Service<Void> {
private final InjectedValue<JMSServerManager> jmsServer = new InjectedValue<JMSServerManager>();
- private final InjectedValue<Executor> executorInjector = new InjectedValue<Executor>();
+ private final InjectedValue<ExecutorService> executorInjector = new InjectedValue<ExecutorService>();
private final String queueName;
@@ -105,7 +105,7 @@ public Void getValue() throws IllegalStateException {
return jmsServer;
}
- public Injector<Executor> getExecutorInjector() {
+ public Injector<ExecutorService> getExecutorInjector() {
return executorInjector;
}
Oops, something went wrong.

0 comments on commit 28b4a21

Please sign in to comment.