Return-Path: X-Original-To: apmail-felix-commits-archive@www.apache.org Delivered-To: apmail-felix-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 933661790E for ; Mon, 20 Oct 2014 07:51:57 +0000 (UTC) Received: (qmail 52330 invoked by uid 500); 20 Oct 2014 07:51:51 -0000 Delivered-To: apmail-felix-commits-archive@felix.apache.org Received: (qmail 52286 invoked by uid 500); 20 Oct 2014 07:51:51 -0000 Mailing-List: contact commits-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list commits@felix.apache.org Received: (qmail 52277 invoked by uid 99); 20 Oct 2014 07:51:51 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 20 Oct 2014 07:51:51 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 20 Oct 2014 07:51:24 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 5885823889E1; Mon, 20 Oct 2014 07:51:22 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1633065 - in /felix/sandbox/pderop/dependencymanager-prototype: org.apache.felix.dependencymanager.benchmark/src/org/apache/felix/dm/benchmark/dependencymanager/ org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/ org.a... Date: Mon, 20 Oct 2014 07:51:21 -0000 To: commits@felix.apache.org From: pderop@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20141020075122.5885823889E1@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: pderop Date: Mon Oct 20 07:51:21 2014 New Revision: 1633065 URL: http://svn.apache.org/r1633065 Log: Change the way the Component's Executors are provided to DepenencyManager: Now you have to register a "ComponentExecutorFactory" in the OSGI registry, and this service will then be used by the ComponentScheduler in order to create an Executor for every created components. It is better to do this instead of tracking a java.util.concurrent.Executor from the OSGi registry, mainly because: - using our own interface allows us to version it (we can't put a version on a java.util.concurrent.Executor interface) - Having a ComponentExecutorFactory service allows us to create a specific Executor for each component. Added: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/tpool/ComponentExecutorFactoryImpl.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentExecutorFactory.java Removed: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/tpool/ThreadPool.java Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.benchmark/src/org/apache/felix/dm/benchmark/dependencymanager/ParallelActivator.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/ConfigurationDependencyTest.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/TestBase.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/device/api/README felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/hello/api/Activator.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/tpool/Activator.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/design.txt felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyManager.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/Activator.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentScheduler.java Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.benchmark/src/org/apache/felix/dm/benchmark/dependencymanager/ParallelActivator.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.benchmark/src/org/apache/felix/dm/benchmark/dependencymanager/ParallelActivator.java?rev=1633065&r1=1633064&r2=1633065&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.benchmark/src/org/apache/felix/dm/benchmark/dependencymanager/ParallelActivator.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.benchmark/src/org/apache/felix/dm/benchmark/dependencymanager/ParallelActivator.java Mon Oct 20 07:51:21 2014 @@ -1,8 +1,9 @@ package org.apache.felix.dm.benchmark.dependencymanager; -import java.util.Hashtable; import java.util.concurrent.Executor; +import org.apache.felix.dm.Component; +import org.apache.felix.dm.ComponentExecutorFactory; import org.apache.felix.dm.DependencyManager; import org.apache.felix.dm.benchmark.scenario.Helper; import org.osgi.framework.BundleContext; @@ -12,9 +13,12 @@ import org.osgi.framework.BundleContext; */ public class ParallelActivator extends Activator { public void init(BundleContext context, DependencyManager mgr) throws Exception { - Hashtable props = new Hashtable<>(); - props.put("target", DependencyManager.THREADPOOL); - context.registerService(Executor.class.getName(), Helper.getThreadPool(), props); + context.registerService(ComponentExecutorFactory.class.getName(), new ComponentExecutorFactory() { + @Override + public Executor getExecutorFor(Component component) { + return Helper.getThreadPool(); + } + }, null); super.init(context, mgr); } } Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/ConfigurationDependencyTest.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/ConfigurationDependencyTest.java?rev=1633065&r1=1633064&r2=1633065&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/ConfigurationDependencyTest.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/ConfigurationDependencyTest.java Mon Oct 20 07:51:21 2014 @@ -72,7 +72,7 @@ public class ConfigurationDependencyTest m.add(s1); m.add(s2); m.add(s3); - e.waitForStep(4, 50000000); + e.waitForStep(4, 5000); m.remove(s1); m.remove(s2); m.remove(s3); Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/TestBase.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/TestBase.java?rev=1633065&r1=1633064&r2=1633065&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/TestBase.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/TestBase.java Mon Oct 20 07:51:21 2014 @@ -12,6 +12,7 @@ import junit.framework.Assert; import junit.framework.TestCase; import org.apache.felix.dm.Component; +import org.apache.felix.dm.ComponentExecutorFactory; import org.apache.felix.dm.DependencyManager; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; @@ -50,7 +51,7 @@ public abstract class TestBase extends T protected volatile DependencyManager m_dm; // The Registration for the DM threadpool. - private ServiceRegistration m_threadPoolRegistration; + private ServiceRegistration m_componentExecutorFactoryReg; public TestBase() { } @@ -70,9 +71,14 @@ public abstract class TestBase extends T if (m_parallel) { warn("Using threadpool ..."); m_threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); - props = new Hashtable<>(); - props.put("target", DependencyManager.THREADPOOL); - m_threadPoolRegistration = context.registerService(Executor.class.getName(), m_threadPool, props); + m_componentExecutorFactoryReg = context.registerService(ComponentExecutorFactory.class.getName(), + new ComponentExecutorFactory() { + @Override + public Executor getExecutorFor(Component component) { + return m_threadPool; + } + }, + null); } } @@ -81,8 +87,8 @@ public abstract class TestBase extends T logService.unregister(); context.removeFrameworkListener(this); clearComponents(); - if (m_parallel && m_threadPoolRegistration != null) { - m_threadPoolRegistration.unregister(); + if (m_parallel && m_componentExecutorFactoryReg != null) { + m_componentExecutorFactoryReg.unregister(); m_threadPool.shutdown(); } Assert.assertFalse(errorsLogged()); Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/device/api/README URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/device/api/README?rev=1633065&r1=1633064&r2=1633065&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/device/api/README (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/device/api/README Mon Oct 20 07:51:21 2014 @@ -1,4 +1,4 @@ -This is an example showing a Dependency Manager "Adapter" in action. two kinds of services are +This is an example showing a Dependency Manager "Adapter" in action. Two kinds of services are registered in the registry: some Device, and some DeviceParameter services. For each Device (having a given id), there is also a corresponding "DeviceParameter" service, having the same id. Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/hello/api/Activator.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/hello/api/Activator.java?rev=1633065&r1=1633064&r2=1633065&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/hello/api/Activator.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/hello/api/Activator.java Mon Oct 20 07:51:21 2014 @@ -19,6 +19,5 @@ public class Activator extends Dependenc .add(createConfigurationDependency() .setPid(ServiceConsumer.class.getName()).setCallback("updated")) .add(createServiceDependency().setService(ServiceProvider.class).setRequired(true))); - } } Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/tpool/Activator.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/tpool/Activator.java?rev=1633065&r1=1633064&r2=1633065&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/tpool/Activator.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/tpool/Activator.java Mon Oct 20 07:51:21 2014 @@ -1,32 +1,20 @@ package org.apache.felix.dependencymanager.samples.tpool; -import java.util.Hashtable; -import java.util.concurrent.Executor; - +import org.apache.felix.dm.ComponentExecutorFactory; import org.apache.felix.dm.DependencyActivatorBase; import org.apache.felix.dm.DependencyManager; import org.osgi.framework.BundleContext; /** - * Registers a threadpool in the OSGi service registry to enable parallelism. - * DependencyManager core will use the threadpool when handling components dependencies and - * components lifecycle callbacks. - * - * Important note: since we are using the DM API to declare our threadpool, we have to disable - * parallelism for our "org.apache.felix.dependencymanager.samples.tpool.ThreadPool" component. - * To do so, we use the - * "org.apache.felix.dependencymanager.parallelism=!org.apache.felix.dependencymanager.samples.tpool,*" - * OSGI service property (see the bnd.bnd file). + * See README file describing this Activator. * * @author Felix Project Team */ public class Activator extends DependencyActivatorBase { @Override public void init(BundleContext context, DependencyManager mgr) throws Exception { - Hashtable props = new Hashtable<>(); - props.put("target", DependencyManager.THREADPOOL); mgr.add(createComponent() - .setInterface(Executor.class.getName(), props) - .setImplementation(ThreadPool.class)); + .setInterface(ComponentExecutorFactory.class.getName(), null) + .setImplementation(ComponentExecutorFactoryImpl.class)); } } Added: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/tpool/ComponentExecutorFactoryImpl.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/tpool/ComponentExecutorFactoryImpl.java?rev=1633065&view=auto ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/tpool/ComponentExecutorFactoryImpl.java (added) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/tpool/ComponentExecutorFactoryImpl.java Mon Oct 20 07:51:21 2014 @@ -0,0 +1,17 @@ +package org.apache.felix.dependencymanager.samples.tpool; + +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +import org.apache.felix.dm.Component; +import org.apache.felix.dm.ComponentExecutorFactory; + +public class ComponentExecutorFactoryImpl implements ComponentExecutorFactory { + final static int SIZE = Runtime.getRuntime().availableProcessors(); + final static Executor m_threadPool = Executors.newFixedThreadPool(SIZE); + + @Override + public Executor getExecutorFor(Component component) { + return m_threadPool; + } +} Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/design.txt URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/design.txt?rev=1633065&r1=1633064&r2=1633065&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/design.txt (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/design.txt Mon Oct 20 07:51:21 2014 @@ -19,57 +19,23 @@ This prototype demonstrates the new conc 20 sept 2014 (pderop): - * Added support for concurrent mode: To allow components to be handled in parallel, you can now - register in the OSGi service registry a threadpool (java.util.concurrent.Executor) service with - a "target=org.apache.felix.dependencymanager" service property. Then, the dependency manager will - use that threadpool for managing components. If you want to ensure that the threadpool is - registered in the OSGi registry before all components are started, you have two choices: - -- you can first use the start level service and manage to start the management agent bundle which - provides the threadpool before all other bundles. - -- If the start level service is not an option, then you can use the - "org.apache.felix.dependencymanager.parallel" OSGi system property. This property allows - to specify all component implementation class name prefixes which have to wait for the thread pool - before being started by Dependency Manager. This property can simply take "*", or a list of - package prefixes (comma separated). This property can also be used to specify some components - which should not be handled using a threadpool, even if one is available from the OSGi - registry. To do so, just use a "!" in front of a given classname prefix. - -For example: if you want to enable parallelism for all components, just set the system property: - - org.apache.felix.dependencymanager.parallel=* - -if you want to enable parallelism for some components whose class names is starting with foo.bar - and foo.zoo: - - org.apache.felix.dependencymanager.parallel=foo.bar, foo.zoo - -if yo want to enable parallelism for all components, except for components whose class names - start with "foo.notparallel", then you can use a negation prefix ("!"), like this: - - org.apache.felix.dependencymanager.parallel=!foo.notparallel, * - -Using the above property, all components will wait for the threadpool, except components which -implementation class names which are starting with "foo.notparallel" prefix. - -- Notice that if the Dependency Manager API is used for declaring a threadpool and all its related - dependent services, then you have to use the "org.apache.felix.dependencymanager.parallel" system - property in order to exclude the threadpool DM components from the list of components using the - threadpool. As an example, you can take a look at the org.apache.felix.dependencymanager.samples - project, which is declaring a threadpool using the Dependency Manager API. The sample is then - using the following property in the org.apache.felix.dependencymanager.samples/bnd.bnd file: + * Added support for parallelism: To allow components to be started and handled in parallel, you can + now register in the OSGi service registry a ComponentExecutorFactory service that is used to get + an Executor for the management of all components dependencies/lifecycle callbacks. See javadoc + from the org.apache.felix.dm.ComponentExecutorFactory interface for more informations. + + You can also take a look at the the org.apache.felix.dependencymanager.samples project, which is + registering a ComponentExecutorFactory from org.apache.felix.dependencymanager.samples.tpool + bundle. + + See also the following property in the org.apache.felix.dependencymanager.samples/bnd.bnd org.apache.felix.dependencymanager.parallel=\ '!org.apache.felix.dependencymanager.samples.tpool, *',\ -Here, all components except those having a package starting with -org.apache.felix.dependencymanager.samples.tpool will wait for the threadpool before being initialized -by Dependency Manager. But the org.apache.felix.dependencymanager.samples.tpool.ThreadPool will not -wait for a threadpool, since *it is* the threadpool ! - - - + Here, all components will be handled by Executors provided by the ComponentExecutorFactory, + except those having a package starting with "org.apache.felix.dependencymanager.samples.tpool" + (because the threadpool is itself defined using the Dependency Manager API). Added: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentExecutorFactory.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentExecutorFactory.java?rev=1633065&view=auto ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentExecutorFactory.java (added) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentExecutorFactory.java Mon Oct 20 07:51:21 2014 @@ -0,0 +1,62 @@ +package org.apache.felix.dm; + +import java.util.concurrent.Executor; + +/** + * A ComponentExecutorFactory service allows to provide a custom Executor (typically a threadpool) + * for a given Component. + * When a Component is added to a DependencyManager, the ComponentExecutorFactory is then + * used to create an Executor for that component and the Executor will be used to execute + * all the DM internal code related to the component's dependency management. The Executor + * will also be used to invoke all the component's lifecycle callbacks. + * + * All the component dependency management/lifecycle callbacks will be handled in the Executor, + * but every dependency events will be handled serially, in FIFO order (it's actually a kind of + * actor thread model). This means that you then don't have to deal with + * synchronizations anymore in your component dependencies/lifecycle callbacks; and multiple + * components will be managed and started concurrently, in parallel. + * + * If you want to ensure that the ComponentExecutorFactory is registered in the OSGI registry + * before all others DM components are added to their respective DependencyManagers, then you + * can simply use the "org.apache.felix.dependencymanager.parallel" OSGi system property, which + * can specify the list of components which must wait for the ComponentExecutorFactory service. + * + * This property value can be set to a wildcard ("*"), or a list of components implementation class prefixes + * (comma separated). So, all components class names starting with the specified prefixes will be cached + * until the ComponentExecutorFactory service is registered (In this way, it is not necessary to use + * the StartLevel service if you want to ensure that all components will be started concurrently). + * + * Some class name prefixes can also be negated (using "!"), in order to exclude some components from the + * list of components using the ComponentExecutorFactory service, or the "getExecutorFor" method can just + * return null for a given component, in order to avoid using an executor for a given component. + * + * Notice that if the ComponentExecutorFactory itself and all it's dependent services are defined using + * the Dependency Manager API, then you have to list the package of such components with a "!" + * prefix, in order to indicate that those components must not wait for a ComponentExecutorFactory service + * (since they are part of the ComponentExecutorFactory implementation !). + * + * Examples: + * + * org.apache.felix.dependencymanager.parallel=* + * -> means all components must be cached until a ComponentExecutorFactory comes up. + * + * org.apache.felix.dependencymanager.parallel=foo.bar, foo.zoo + * -> means only components whose implementation class names are starting with "foo.bar" or "foo.zoo" + * must be handled using an Executor returned by the ComponentExecutorFactory service. + * + * org.apache.felix.dependencymanager.parallel=!foo.threadpool, * + * -> means all components must be delayed until the ComponentExecutorFactory comes up, except the + * components whose implementations class names are starting with "foo.threadpool" prefix). + * + * @author Felix Project Team + */ +public interface ComponentExecutorFactory { + /** + * Returns an Executor (typically or thread pool) used to handle the component's dependencies + * and invoke all component lifecycle callbacks. + * + * @param component the Component to be managed by the returned Executor + * @return an Executor used to manage the given component, or null if the component must not be managed using any executor. + */ + Executor getExecutorFor(Component component); +} Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyManager.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyManager.java?rev=1633065&r1=1633064&r2=1633065&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyManager.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyManager.java Mon Oct 20 07:51:21 2014 @@ -60,12 +60,7 @@ import org.osgi.framework.FrameworkUtil; * * @author Felix Project Team */ -public class DependencyManager { - /** - * A management agent can register a threadpool in the registry using a "target" property with the following value - */ - public static final String THREADPOOL = "org.apache.felix.dependencymanager"; - +public class DependencyManager { /** * The DependencyManager Activator will wait for a threadpool before creating any DM components if the following * OSGi system property is set to true. Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/Activator.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/Activator.java?rev=1633065&r1=1633064&r2=1633065&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/Activator.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/Activator.java Mon Oct 20 07:51:21 2014 @@ -18,18 +18,16 @@ */ package org.apache.felix.dm.impl; -import java.util.concurrent.Executor; - +import org.apache.felix.dm.ComponentExecutorFactory; import org.apache.felix.dm.DependencyActivatorBase; import org.apache.felix.dm.DependencyManager; import org.osgi.framework.BundleContext; /** - * DependencyManager Activator. We are using this activator in order to track and use a threadpool, which can be - * optionally registered by any management agent bundle. - * The management agent can just register a java.util.Executor service in the service registry - * using the "target=org.apache.felix.dependencymanager" property. - * + * DependencyManager Activator used to track a ComponentExecutorFactory service optionally registered by + * a management agent bundle. + * + * @see {@link ComponentExecutorFactory} * @author Felix Project Team */ public class Activator extends DependencyActivatorBase { @@ -38,7 +36,7 @@ public class Activator extends Dependenc mgr.add(createComponent() .setImplementation(ComponentScheduler.instance()) .add(createServiceDependency() - .setService(Executor.class, "(target=" + DependencyManager.THREADPOOL + ")") + .setService(ComponentExecutorFactory.class) .setRequired(true) .setCallbacks("bind", "unbind"))); } Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentScheduler.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentScheduler.java?rev=1633065&r1=1633064&r2=1633065&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentScheduler.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentScheduler.java Mon Oct 20 07:51:21 2014 @@ -24,50 +24,23 @@ import java.util.concurrent.Executor; import org.apache.felix.dm.Component; import org.apache.felix.dm.ComponentDeclaration; +import org.apache.felix.dm.ComponentExecutorFactory; import org.apache.felix.dm.context.ComponentContext; import org.osgi.framework.BundleContext; +import org.osgi.service.component.ComponentFactory; /** - * The Dependency Manager delegates all components addition/removal to this class, which is in charge of tracking - * a threadpool from the OSGi registry in order to handle components concurrently. + * The Dependency Manager delegates all components addition/removal to this class. + * If a ComponentExecutorFactory is registered in the OSGi registry, this class will use it to get an + * Executor used for components management and lifecycle callbacks. * - * By default, an external management bundle may register a threadpool (java.util.concurrent.Executor) with a - * special "target=org.apache.felix.dependencymanager" service property. So, if the threadpool is registered, then - * any components added will use that threadpool. - * - * If you want to ensure that all components must wait for a threadpool, before they are actually added - * in a dependency manager, you can simply use the "org.apache.felix.dependencymanager.parallel" OSGi system - * property, which can specify the list of components which must wait for the threadpool. - * This property value can be a wildcard ("*"), or a list of components implementation class prefixes - * (comma seperated). So, all components class names starting with the specified prefixes will be cached until the - * threadpool becomes available. - * Some class name prefixes can also be negated (using "!"), in order to exclude some components from the list of - * components using the threadpool. - * - * Notice that if the threadpool and all the services it may depends on are also declared using the - * Dependency Manager API, then you have to list the package of such components with a "!" prefix, in order to - * indicate that those components must not wait for a threadpool (since they are part of the threadpool - * implementation !). - * - * Examples: - * - * org.apache.felix.dependencymanager.parallel=* - * -> means all components must be cached until a threadpool comes up. - * - * org.apache.felix.dependencymanager.parallel=foo.bar, foo.zoo - * -> means only components whose implementation class names is starting with "foo.bar" or "foo.zoo" must wait for and - * use a threadpool. - * - * org.apache.felix.dependencymanager.parallel=!foo.threadpool, * - * -> means all components must wait for and use a threadpool, except the threadpool components implementations class names - * (starting with foo.threadpool prefix). - * + * @see {@link ComponentFactory} * @author Felix Project Team */ public class ComponentScheduler { private final static ComponentScheduler m_instance = new ComponentScheduler(); private final static String PARALLEL = "org.apache.felix.dependencymanager.parallel"; - private volatile Executor m_threadPool; + private volatile ComponentExecutorFactory m_componentExecutorFactory; private final Executor m_serial = new SerialExecutor(null); private Set m_pending = new LinkedHashSet<>(); @@ -75,13 +48,13 @@ public class ComponentScheduler { return m_instance; } - protected void bind(final Executor threadPool) { - m_threadPool = threadPool; + protected void bind(final ComponentExecutorFactory componentExecutorFactory) { + m_componentExecutorFactory = componentExecutorFactory; m_serial.execute(new Runnable() { @Override public void run() { for (Component c : m_pending) { - ((ComponentContext) c).setThreadPool(threadPool); + createComponentExecutor(m_componentExecutorFactory, c); ((ComponentContext) c).start(); } m_pending.clear(); @@ -90,7 +63,7 @@ public class ComponentScheduler { } protected void unbind(Executor threadPool) { - m_threadPool = null; + m_componentExecutorFactory = null; } public void add(final Component c) { @@ -102,12 +75,12 @@ public class ComponentScheduler { m_serial.execute(new Runnable() { @Override public void run() { - Executor threadPool = m_threadPool; - if (threadPool == null) { + ComponentExecutorFactory execFactory = m_componentExecutorFactory; + if (execFactory == null) { m_pending.add(c); } else { - ((ComponentContext) c).setThreadPool(threadPool); + createComponentExecutor(execFactory, c); ((ComponentContext) c).start(); } } @@ -127,14 +100,14 @@ public class ComponentScheduler { } private boolean mayStartNow(Component c) { - Executor threadPool = m_threadPool; + ComponentExecutorFactory execFactory = m_componentExecutorFactory; BundleContext ctx = c.getDependencyManager().getBundleContext(); String parallel = ctx.getProperty(PARALLEL); - if (threadPool == null) { - // No threadpool available. If a "parallel" OSGi system property is specified, we have to wait for a - // threadpool if the component class name is matching one of the prefixes specified in the "parallel" - // system property. + if (execFactory == null) { + // No ComponentExecutorFactory available. If a "parallel" OSGi system property is specified, + // we have to wait for a ComponentExecutorFactory servoce if the component class name is matching one of the + // prefixes specified in the "parallel" system property. if (parallel != null && requiresThreadPool(c, parallel)) { return false; // wait for a threadpool } else { @@ -147,7 +120,7 @@ public class ComponentScheduler { // But if the "parallel" system property is specified, the component will use the threadpool only if it's // classname is starting with one of the prefixes specified in the property. if (parallel == null || requiresThreadPool(c, parallel)) { - ((ComponentContext) c).setThreadPool(threadPool); + ((ComponentContext) c).setThreadPool(execFactory.getExecutorFor(c)); } return true; // start the component now, possibly using the threadpool (see above). } @@ -172,4 +145,11 @@ public class ComponentScheduler { } return false; } + + private void createComponentExecutor(ComponentExecutorFactory execFactory, Component c) { + Executor exec = execFactory.getExecutorFor(c); + if (exec != null) { + ((ComponentContext) c).setThreadPool(exec); + } + } }