This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.commons.threads-3.0.2 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-threads.git
commit 8145a6dd9de8132dc18af4f110ff2e0fdccd420d Author: Carsten Ziegeler <[email protected]> AuthorDate: Fri Aug 27 08:36:15 2010 +0000 SLING-1699 : New default configuration is created on each startup git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/threads@990068 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 9 ++ .../sling/commons/threads/impl/Activator.java | 10 ++ .../threads/impl/DefaultThreadPoolManager.java | 105 +++++++------------ .../commons/threads/impl/WebConsolePrinter.java | 115 +++++++++++++++++++++ src/main/resources/OSGI-INF/metatype/metatype.xml | 6 +- 5 files changed, 173 insertions(+), 72 deletions(-) diff --git a/pom.xml b/pom.xml index 1f2701f..e67b911 100644 --- a/pom.xml +++ b/pom.xml @@ -63,6 +63,9 @@ <Private-Package> org.apache.sling.commons.threads.impl </Private-Package> + <Import-Package> + org.apache.felix.webconsole;resolution:=optional, * + </Import-Package> </instructions> </configuration> </plugin> @@ -94,5 +97,11 @@ <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.webconsole</artifactId> + <version>3.0.0</version> + <scope>provided</scope> + </dependency> </dependencies> </project> diff --git a/src/main/java/org/apache/sling/commons/threads/impl/Activator.java b/src/main/java/org/apache/sling/commons/threads/impl/Activator.java index 7d02ae5..1e76887 100644 --- a/src/main/java/org/apache/sling/commons/threads/impl/Activator.java +++ b/src/main/java/org/apache/sling/commons/threads/impl/Activator.java @@ -54,12 +54,22 @@ public class Activator implements BundleActivator { this.service = new DefaultThreadPoolManager(this.bundleContext, props); this.serviceReg = this.bundleContext.registerService(new String[] {ThreadPoolManager.class.getName(), ManagedServiceFactory.class.getName()}, service, props); + try { + WebConsolePrinter.initPlugin(this.bundleContext, this.service); + } catch (Throwable ignore) { + // we just ignore this + } } /** * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) */ public void stop(BundleContext context) { + try { + WebConsolePrinter.destroyPlugin(); + } catch (Throwable ignore) { + // we just ignore this + } if ( this.serviceReg != null ) { this.serviceReg.unregister(); this.serviceReg = null; diff --git a/src/main/java/org/apache/sling/commons/threads/impl/DefaultThreadPoolManager.java b/src/main/java/org/apache/sling/commons/threads/impl/DefaultThreadPoolManager.java index 3fbbc09..318e2cc 100644 --- a/src/main/java/org/apache/sling/commons/threads/impl/DefaultThreadPoolManager.java +++ b/src/main/java/org/apache/sling/commons/threads/impl/DefaultThreadPoolManager.java @@ -16,10 +16,8 @@ */ package org.apache.sling.commons.threads.impl; -import java.io.IOException; import java.util.Dictionary; import java.util.HashMap; -import java.util.Hashtable; import java.util.Map; import java.util.UUID; @@ -31,11 +29,8 @@ import org.apache.sling.commons.threads.ThreadPoolConfig.ThreadPoolPolicy; import org.apache.sling.commons.threads.ThreadPoolConfig.ThreadPriority; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; -import org.osgi.service.cm.Configuration; -import org.osgi.service.cm.ConfigurationAdmin; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ManagedServiceFactory; -import org.osgi.util.tracker.ServiceTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,18 +53,13 @@ public class DefaultThreadPoolManager /** The bundle context. */ protected final BundleContext bundleContext; - /** Service tracker for the config admin. */ - protected final ServiceTracker configAdminTracker; - /** * Constructor and activate this component. */ public DefaultThreadPoolManager(final BundleContext bc, final Dictionary<String, Object> props) { this.properties = props; this.bundleContext = bc; - this.configAdminTracker = new ServiceTracker(bc, ConfigurationAdmin.class.getName(), null); - this.configAdminTracker.open(); - this.logger.info("Started Apache Sling Thread Pool Manager: {}", getPid()); + this.logger.info("Started Apache Sling Thread Pool Manager"); } /** @@ -78,42 +68,13 @@ public class DefaultThreadPoolManager public void destroy() { this.logger.debug("Disposing all thread pools"); - this.configAdminTracker.close(); - synchronized ( this.pools ) { for (final Entry entry : this.pools.values()) { entry.shutdown(); } this.pools.clear(); } - this.logger.info("Stopped Apache Sling Thread Pool Manager."); - } - - /** - * Helper method to get the pid - */ - private String getPid() { - // as the activator put a string in the props we know that this is a string - return this.properties.get(Constants.SERVICE_PID).toString(); - } - - /** - * Create a dictionary with configuration properties for the configuration - */ - private Dictionary<String, Object> getProperties(final String poolName, final ThreadPoolConfig config) { - final Dictionary<String, Object> props = new Hashtable<String, Object>(); - props.put(ModifiableThreadPoolConfig.PROPERTY_MIN_POOL_SIZE, config.getMinPoolSize()); - props.put(ModifiableThreadPoolConfig.PROPERTY_MAX_POOL_SIZE, config.getMaxPoolSize()); - props.put(ModifiableThreadPoolConfig.PROPERTY_QUEUE_SIZE, config.getQueueSize()); - props.put(ModifiableThreadPoolConfig.PROPERTY_KEEP_ALIVE_TIME, config.getKeepAliveTime()); - props.put(ModifiableThreadPoolConfig.PROPERTY_BLOCK_POLICY, config.getBlockPolicy().toString()); - props.put(ModifiableThreadPoolConfig.PROPERTY_SHUTDOWN_GRACEFUL, config.isShutdownGraceful()); - props.put(ModifiableThreadPoolConfig.PROPERTY_SHUTDOWN_WAIT_TIME, config.getShutdownWaitTimeMs()); - props.put(ModifiableThreadPoolConfig.PROPERTY_PRIORITY, config.getPriority().toString()); - props.put(ModifiableThreadPoolConfig.PROPERTY_DAEMON, config.isDaemon()); - props.put(ModifiableThreadPoolConfig.PROPERTY_NAME, poolName); - - return props; + this.logger.info("Stopped Apache Sling Thread Pool Manager"); } /** @@ -162,30 +123,11 @@ public class DefaultThreadPoolManager if ( entry == null ) { this.logger.debug("Creating new pool with name {}", poolName); final ModifiableThreadPoolConfig config = new ModifiableThreadPoolConfig(); - // check for config admin - final ConfigurationAdmin ca = (ConfigurationAdmin) this.configAdminTracker.getService(); - if ( ca != null ) { - try { - final Configuration caConfig = ca.createFactoryConfiguration(getPid()); - caConfig.update(this.getProperties(poolName, config)); - entry = new Entry(caConfig.getProperties().get(Constants.SERVICE_PID).toString(), config, poolName); - } catch (IOException e) { - // there is not much we can do if we get an io exception - // just log and continue - this.logger.error("Unable to create configuration for thread pool " + poolName, e); - } - } else { - this.logger.error("Configuration admin is not available."); - } - // sanity check - if CA is not available or a problem occured during persisting - // we don't have an entry - if ( entry == null ) { - entry = new Entry(null, config, poolName); - } + entry = new Entry(null, config, poolName); + this.pools.put(poolName, entry); } return entry.incUsage(); - } } @@ -227,6 +169,15 @@ public class DefaultThreadPoolManager } /** + * Return all configurations for the web console printer + */ + public Entry[] getConfigurations() { + synchronized ( this.pools ) { + return this.pools.values().toArray(new Entry[this.pools.size()]); + } + } + + /** * @see org.osgi.service.cm.ManagedServiceFactory#updated(java.lang.String, java.util.Dictionary) */ @SuppressWarnings("unchecked") @@ -238,15 +189,26 @@ public class DefaultThreadPoolManager } this.logger.debug("Updating {} with {}", pid, properties); synchronized ( this.pools ) { + final ThreadPoolConfig config = this.createConfig(properties); + Entry foundEntry = null; - // we have to search the config by using the pid! + // we have to search the config by using the pid first! for (final Entry entry : this.pools.values()) { if ( pid.equals(entry.getPid()) ) { foundEntry = entry; break; } } - final ThreadPoolConfig config = this.createConfig(properties); + // if we haven't found it by pid we search by name + if ( foundEntry == null ) { + for (final Entry entry : this.pools.values()) { + if ( name.equals(entry.getName()) ) { + foundEntry = entry; + break; + } + } + } + if ( foundEntry != null ) { // if the name changed - we have to reregister(!) if ( !name.equals(foundEntry.getName()) ) { @@ -254,7 +216,7 @@ public class DefaultThreadPoolManager this.pools.put(name, foundEntry); } // update - foundEntry.update(config, name); + foundEntry.update(config, name, pid); } else { // create this.pools.put(name, new Entry(pid, config, name)); @@ -283,16 +245,16 @@ public class DefaultThreadPoolManager if ( foundEntry.isUsed() ) { // we register this with a new name final String name = "ThreadPool-" + UUID.randomUUID().toString(); - foundEntry.update(new ModifiableThreadPoolConfig(), name); + foundEntry.update(new ModifiableThreadPoolConfig(), name, null); this.pools.put(name, foundEntry); } } } } - private static final class Entry { + protected static final class Entry { /** The configuration pid. (might be null for anonymous pools.*/ - private final String pid; + private volatile String pid; /** Usage count. */ private volatile int count; @@ -338,7 +300,7 @@ public class DefaultThreadPoolManager } } - public void update(final ThreadPoolConfig config, final String name) { + public void update(final ThreadPoolConfig config, final String name, final String pid) { if ( this.pool != null ) { this.pool.setName(name); if ( !this.config.equals(config) ) { @@ -347,6 +309,7 @@ public class DefaultThreadPoolManager } this.config = config; this.name = name; + this.pid = pid; } public String getName() { @@ -356,5 +319,9 @@ public class DefaultThreadPoolManager public boolean isUsed() { return this.count > 0; } + + public ThreadPoolConfig getConfig() { + return this.config; + } } } diff --git a/src/main/java/org/apache/sling/commons/threads/impl/WebConsolePrinter.java b/src/main/java/org/apache/sling/commons/threads/impl/WebConsolePrinter.java new file mode 100644 index 0000000..b0aedf0 --- /dev/null +++ b/src/main/java/org/apache/sling/commons/threads/impl/WebConsolePrinter.java @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.sling.commons.threads.impl; + +import java.io.PrintWriter; +import java.util.Dictionary; +import java.util.Hashtable; + +import org.apache.felix.webconsole.ConfigurationPrinter; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.ServiceRegistration; + +/** + * This is a configuration printer for the web console which + * prints out the thread pools. + * + */ +public class WebConsolePrinter implements ConfigurationPrinter { + + private static ServiceRegistration plugin; + + public static void initPlugin(final BundleContext bundleContext, + final DefaultThreadPoolManager dtpm) { + final WebConsolePrinter propertiesPrinter = new WebConsolePrinter(dtpm); + final Dictionary<String, String> props = new Hashtable<String, String>(); + props.put(Constants.SERVICE_DESCRIPTION, + "Apache Sling Thread Pool Configuration Printer"); + props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation"); + + plugin = bundleContext.registerService(ConfigurationPrinter.class.getName(), + propertiesPrinter, props); + } + + public static void destroyPlugin() { + if ( plugin != null) { + plugin.unregister(); + plugin = null; + } + } + + private static String HEADLINE = "Apache Sling Thread Pools"; + + private final DefaultThreadPoolManager mgr; + + public WebConsolePrinter(final DefaultThreadPoolManager dtpm) { + this.mgr = dtpm; + } + + /** + * @see org.apache.felix.webconsole.ConfigurationPrinter#getTitle() + */ + public String getTitle() { + return "Sling Thread Pools"; + } + + /** + * Print out the servlet filter chains. + * @see org.apache.felix.webconsole.ConfigurationPrinter#printConfiguration(java.io.PrintWriter) + */ + public void printConfiguration(PrintWriter pw) { + pw.println(HEADLINE); + pw.println(); + final DefaultThreadPoolManager.Entry[] configs = this.mgr.getConfigurations(); + if ( configs.length > 0 ) { + for(final DefaultThreadPoolManager.Entry entry : configs ) { + pw.print("Pool "); + pw.println(entry.getName()); + if ( entry.getPid() != null ) { + pw.print("- from configuration : "); + pw.println(entry.getPid()); + } + pw.print("- used : "); + pw.println(entry.isUsed()); + pw.print("- min pool size : "); + pw.println(entry.getConfig().getMinPoolSize()); + pw.print("- max pool size : "); + pw.println(entry.getConfig().getMaxPoolSize()); + pw.print("- queue size : "); + pw.println(entry.getConfig().getQueueSize()); + pw.print("- keep alive time : "); + pw.println(entry.getConfig().getKeepAliveTime()); + pw.print("- block policy : "); + pw.println(entry.getConfig().getBlockPolicy()); + pw.print("- priority : "); + pw.println(entry.getConfig().getPriority()); + pw.print("- shutdown graceful : "); + pw.println(entry.getConfig().isShutdownGraceful()); + pw.print("- shutdown wait time : "); + pw.println(entry.getConfig().getShutdownWaitTimeMs()); + pw.print("- daemon : "); + pw.println(entry.getConfig().isDaemon()); + pw.println(); + } + } else { + pw.println("No pools configured."); + } + } +} diff --git a/src/main/resources/OSGI-INF/metatype/metatype.xml b/src/main/resources/OSGI-INF/metatype/metatype.xml index 6e3ff8c..a6c3f73 100644 --- a/src/main/resources/OSGI-INF/metatype/metatype.xml +++ b/src/main/resources/OSGI-INF/metatype/metatype.xml @@ -32,7 +32,7 @@ type="Integer" default="5" name="%minPoolSize.name" description="%minPoolSize.description"/> <metatype:AD id="maxPoolSize" - type="Integer" default="5" name="%queueSize.name" + type="Integer" default="5" name="%maxPoolSize.name" description="%maxPoolSize.description" /> <metatype:AD id="queueSize" type="Integer" default="-1" name="%queueSize.name" @@ -52,10 +52,10 @@ type="Boolean" default="false" name="%shutdownGraceful.name" description="%shutdownGraceful.description" /> <metatype:AD id="daemon" - type="Integer" default="-1" name="%daemon.name" + type="Boolean" default="false" name="%daemon.name" description="%daemon.description" /> <metatype:AD id="shutdownWaitTime" - type="Boolean" default="false" name="%shutdownWaitTime.name" + type="Integer" default="-1" name="%shutdownWaitTime.name" description="%shutdownWaitTime.description" /> <metatype:AD id="priority" type="String" default="NORM" name="%priority.name" -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
