felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pde...@apache.org
Subject svn commit: r1620781 - in /felix/sandbox/pderop/dependencymanager-prototype: org.apache.felix.dm.benchmark/src/org/apache/felix/dm/benchmark/dependencymanager/ org.apache.felix.dm.itest/src/org/apache/felix/dm/itest/ org.apache.felix.dm.shell/test/test...
Date Wed, 27 Aug 2014 06:46:34 GMT
Author: pderop
Date: Wed Aug 27 06:46:34 2014
New Revision: 1620781

URL: http://svn.apache.org/r1620781
Log:
Re added the DependencyManager.setThreadPool method which is sometimes useful, especially
when writing integration tests.
Fixed bug in ComponentScheduler, where threadpool registered by a management agent (using
the DM api) was not correctly 
handled.

Modified:
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.benchmark/src/org/apache/felix/dm/benchmark/dependencymanager/ParallelActivator.java
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.itest/src/org/apache/felix/dm/itest/TestBase.java
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.shell/test/test/DMCommandTest.java
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/DependencyManager.java
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/Activator.java
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/ComponentScheduler.java

Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.benchmark/src/org/apache/felix/dm/benchmark/dependencymanager/ParallelActivator.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.benchmark/src/org/apache/felix/dm/benchmark/dependencymanager/ParallelActivator.java?rev=1620781&r1=1620780&r2=1620781&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.benchmark/src/org/apache/felix/dm/benchmark/dependencymanager/ParallelActivator.java
(original)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.benchmark/src/org/apache/felix/dm/benchmark/dependencymanager/ParallelActivator.java
Wed Aug 27 06:46:34 2014
@@ -1,8 +1,5 @@
 package org.apache.felix.dm.benchmark.dependencymanager;
 
-import java.util.Properties;
-import java.util.concurrent.Executor;
-
 import org.apache.felix.dm.DependencyManager;
 import org.apache.felix.dm.benchmark.scenario.Helper;
 import org.osgi.framework.BundleContext;
@@ -11,10 +8,8 @@ import org.osgi.framework.BundleContext;
  * Parallel version of our default Activator.
  */
 public class ParallelActivator extends Activator {
-    public void start(BundleContext context) throws Exception {
-        Properties props = new Properties();
-        props.put("target", DependencyManager.THREADPOOL);
-        context.registerService(Executor.class.getName(), Helper.getThreadPool(), props);
-        super.start(context);
+    public void init(BundleContext context, DependencyManager mgr) throws Exception {  
+        mgr.setThreadPool(Helper.getThreadPool());
+        super.init(context, mgr);
     }
 }

Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.itest/src/org/apache/felix/dm/itest/TestBase.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.itest/src/org/apache/felix/dm/itest/TestBase.java?rev=1620781&r1=1620780&r2=1620781&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.itest/src/org/apache/felix/dm/itest/TestBase.java
(original)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.itest/src/org/apache/felix/dm/itest/TestBase.java
Wed Aug 27 06:46:34 2014
@@ -52,8 +52,6 @@ public abstract class TestBase extends T
     // Our dependency manager used to create test components.
     protected volatile DependencyManager m_dm;
 
-    private ServiceRegistration m_threadPoolRegistration;
-        
     public TestBase() {
     }
        
@@ -68,10 +66,8 @@ public abstract class TestBase extends T
         context.addFrameworkListener(this);
         m_dm = new DependencyManager(context);
         if (m_parallel) {
-            warn("Registering threadpool ...");
-            Properties props = new Properties();
-            props.put("target", DependencyManager.THREADPOOL);
-            m_threadPoolRegistration = context.registerService(Executor.class.getName(),
m_threadPool, props);
+            warn("Using threadpool ...");
+            m_dm.setThreadPool(m_threadPool);
         }
     }
     
@@ -80,10 +76,6 @@ public abstract class TestBase extends T
     	logService.unregister();
     	context.removeFrameworkListener(this);
     	clearComponents();
-    	if (m_parallel) {
-            warn("Unregistering threadpool ...");
-    	    m_threadPoolRegistration.unregister();
-    	}
     }
         
     protected DependencyManager getDM() {

Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.shell/test/test/DMCommandTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.shell/test/test/DMCommandTest.java?rev=1620781&r1=1620780&r2=1620781&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.shell/test/test/DMCommandTest.java
(original)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm.shell/test/test/DMCommandTest.java
Wed Aug 27 06:46:34 2014
@@ -43,9 +43,7 @@ import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Spy;
 import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Filter;
 
 public class DMCommandTest {
     /** System output just used to debug **/
@@ -68,18 +66,6 @@ public class DMCommandTest {
         when(m_bundleContext.getBundle()).thenReturn(bundle);
         System.setOut(new PrintStream(outContent));
         System.setErr(new PrintStream(errContent));
-
-        // We have to call the DM Activator manually. But before, since the DM Activator
is defining a
-        // dependency over an optional executor, we first have to mock the proper OSGi filter
because
-        // The ServiceTracker will need it ...
-        Filter filter = mock(Filter.class);
-        when(m_bundleContext.createFilter("(&(objectClass=java.util.concurrent.Executor)(target=org.apache.felix.dependencymanager))")).thenReturn(filter);
-
-        // Now, invoke the DM Activator manually.
-        Class dmActivatorClass = Class.forName("org.apache.felix.dm.impl.Activator");
-        BundleActivator dmActivator = (BundleActivator) dmActivatorClass.newInstance();
-        dmActivator.start(m_bundleContext);
-        
         dm = new DependencyManager(m_bundleContext);
         dme = new DMCommand(m_bundleContext);
         DependencyManager.getDependencyManagers().add(dm);

Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/DependencyManager.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/DependencyManager.java?rev=1620781&r1=1620780&r2=1620781&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/DependencyManager.java
(original)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/DependencyManager.java
Wed Aug 27 06:46:34 2014
@@ -80,6 +80,7 @@ public class DependencyManager {
     private final BundleContext m_context;
     private final Logger m_logger;
     private final List<Component> m_components = new CopyOnWriteArrayList<>();
+    private volatile Executor m_threadPool;
 
     // service registry cache
     private static ServiceRegistryCache m_serviceRegistryCache;
@@ -137,6 +138,15 @@ public class DependencyManager {
     }
     
     /**
+     * Sets a threadpool to this dependency manager. All added/removed components will then
be handled
+     * in parallel, using the provided threadpool.
+     */
+    public DependencyManager setThreadPool(Executor threadPool) {
+        m_threadPool = threadPool;
+        return this;
+    }
+
+    /**
      * Returns the list of currently created dependency managers.
      * @return the list of currently created dependency managers
      */
@@ -178,9 +188,14 @@ public class DependencyManager {
      */
     public void add(Component c) {
         m_components.add(c);
-        // Adding the component is delegated to the ComponentScheduler, which will possibly
use a threadpool
-        // in order to add the component in parallel.
-        ComponentScheduler.instance().add(c);
+        if (useComponentScheduler()) {
+            ComponentScheduler.instance().add(c);
+        } else {
+            if (m_threadPool != null) {
+                ((ComponentContext) c).setThreadPool(m_threadPool);
+            }
+            ((ComponentContext) c).start(); 
+        }
     }
 
     /**
@@ -190,7 +205,11 @@ public class DependencyManager {
      * @param service the service to remove
      */
     public void remove(Component c) {
-        ComponentScheduler.instance().remove(c);
+        if (useComponentScheduler()) {
+            ComponentScheduler.instance().remove(c);
+        } else {
+            ((ComponentContext) c).stop();
+        }
         m_components.remove(c);
     }
 
@@ -682,4 +701,8 @@ public class DependencyManager {
             return context;
         }
     }
+    
+    private boolean useComponentScheduler() {
+        return m_threadPool == null && "true".equalsIgnoreCase(m_context.getProperty(DependencyManager.PARALLEL));
+    }
 }

Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/Activator.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/Activator.java?rev=1620781&r1=1620780&r2=1620781&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/Activator.java
(original)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/Activator.java
Wed Aug 27 06:46:34 2014
@@ -20,43 +20,31 @@ package org.apache.felix.dm.impl;
 
 import java.util.concurrent.Executor;
 
-import org.apache.felix.dm.Component;
 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 use a threadpool,
which can be 
- * optionally provided  by any management agent bundle.
- * The management agent can just register a <code>java.util.Executor</code> service
in the osgi registry
- * using the "target=org.apache.felix.dependencymanager" system property.
- * 
- * There are two ways to ensure that all DM components are handled in parallel using the
threadpool:
- * 
- * 1- the management agent bundle can simply be started before any bundles, using the start-level
service.
- * 2- if the start-level service can't be used, then you can configure the org.apache.felix.dependendencymanager.parallel
- *    system property, in order to ask DM to wait for the threadpool, before creating any
DM components.
+ * 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 <code>java.util.Executor</code> service
in the service registry
+ * using the "target=org.apache.felix.dependencymanager" property, and the "org.apache.felix.dependencymanager.parallel"
+ * OSGi system property must also be configured to "true".
  *    
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class Activator extends DependencyActivatorBase {
     @Override
-    public void init(BundleContext context, DependencyManager manager) throws Exception {
-        boolean waitForThreadPool = Boolean.valueOf(context.getProperty(DependencyManager.PARALLEL));
-        Component c = createComponent().setImplementation(ComponentScheduler.instance());
+    public void init(BundleContext ctx, DependencyManager mgr) throws Exception {
+        boolean parallelModeEnabled = Boolean.valueOf(ctx.getProperty(DependencyManager.PARALLEL));
         
-        if (waitForThreadPool) {
-            c.add(createTemporalServiceDependency(10000)
-                .setService(Executor.class, "(target=" + DependencyManager.THREADPOOL + ")")
-                .setRequired(true)
-                .setAutoConfig("m_threadPool"));
-        } else {
-            c.add(createServiceDependency()
-                .setService(Executor.class, "(target=" + DependencyManager.THREADPOOL + ")")
-                .setRequired(false)
-                .setAutoConfig("m_threadPool")
-                .setDefaultImplementation(ComponentScheduler.NullExecutor.class));
+        if (parallelModeEnabled) {
+            mgr.add(createComponent()
+                    .setImplementation(ComponentScheduler.instance())
+                    .add(createTemporalServiceDependency(10000)
+                        .setService(Executor.class, "(target=" + DependencyManager.THREADPOOL
+ ")")
+                        .setRequired(true)
+                        .setAutoConfig("m_threadPool")));
         }
-        manager.add(c);
     }
 }

Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/ComponentScheduler.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/ComponentScheduler.java?rev=1620781&r1=1620780&r2=1620781&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/ComponentScheduler.java
(original)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/ComponentScheduler.java
Wed Aug 27 06:46:34 2014
@@ -1,7 +1,7 @@
 package org.apache.felix.dm.impl;
 
 import java.util.Dictionary;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Set;
 import java.util.concurrent.Executor;
 
@@ -11,15 +11,10 @@ import org.apache.felix.dm.DependencyMan
 import org.apache.felix.dm.context.ComponentContext;
 
 /**
- * Components addition/removal made through the DependencyManagerAPI are delegated to this
- * scheduler, which will use a threadpool optionally provided by any management bundle. 
- * The management bundle can register a threadpool (java.util.Executor) in the osgi registry
- * using the "target=org.apache.felix.dependencymanager" service property.
- * 
- * If the "org.apache.felix.dependencymanager.parallel" OSGi service property is set to true,
- * then the scheduler will wait for a threadpool before creating any DM components (that
is:
- * added components will be cached until threadpool comes up from the OSGi service registry.

- * 
+ * When a DependencyManager is not explicitely configured with a threadpool, and when parallel
mode is enabled,
+ * then added components are delegated to this class, which will cache all added components
until one threadpool
+ * is registered in the OSGi service registry.
+ *  
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class ComponentScheduler {
@@ -27,24 +22,19 @@ public class ComponentScheduler {
     private volatile Executor m_threadPool;
     private final Executor m_serial = new SerialExecutor(null);
     private boolean m_started;
-    private Set<Component> m_pending = new HashSet<>();
-    public final static class NullExecutor implements Executor {
-        @Override
-        public void execute(Runnable command) {
-        }
-    };
+    private Set<Component> m_pending = new LinkedHashSet<>();
 
     public static ComponentScheduler instance() {
         return m_instance;
     }
 
-    public void start() {
+    protected void start() {
         m_serial.execute(new Runnable() {
             @Override
             public void run() {
                 m_started = true;
                 for (Component c : m_pending) {
-                    doAdd(c);
+                    addUsingThreadPool(c);
                 }
                 m_pending.clear();
             }
@@ -52,9 +42,10 @@ public class ComponentScheduler {
     }
 
     public void add(final Component c) {
-        if (! isParallelComponent(c)) {
+        if (!isParallelComponent(c)) {
             ((ComponentContext) c).start();
-        } else {
+        }
+        else {
             m_serial.execute(new Runnable() {
                 @Override
                 public void run() {
@@ -62,7 +53,7 @@ public class ComponentScheduler {
                         m_pending.add(c);
                     }
                     else {
-                        doAdd(c);
+                        addUsingThreadPool(c);
                     }
                 }
             });
@@ -70,9 +61,10 @@ public class ComponentScheduler {
     }
 
     public void remove(final Component c) {
-        if (! isParallelComponent(c)) {
+        if (!isParallelComponent(c)) {
             ((ComponentContext) c).stop();
-        } else {
+        }
+        else {
             m_serial.execute(new Runnable() {
                 @Override
                 public void run() {
@@ -80,39 +72,34 @@ public class ComponentScheduler {
                         m_pending.remove(c);
                     }
                     else {
-                        doRemove(c);
+                        ((ComponentContext) c).stop();
                     }
                 }
             });
         }
     }
 
-    private void doAdd(Component c) {
-        if (! (m_threadPool instanceof NullExecutor)) {
-            ((ComponentContext) c).setThreadPool(m_threadPool);
-        }
+    private void addUsingThreadPool(Component c) {
+        ((ComponentContext) c).setThreadPool(m_threadPool);
         ((ComponentContext) c).start();
     }
 
-    private void doRemove(Component c) {
-        ((ComponentContext) c).stop();
-    }
-    
     private boolean isParallelComponent(Component c) {
-        ComponentDeclaration decl = c.getComponentDeclaration();
-        
         // The component declared from our DM Activator can not be parallel.
+        ComponentDeclaration decl = c.getComponentDeclaration();
         if (ComponentScheduler.class.getName().equals(decl.getName())) {
             return false;
         }
-        
-        // A threadpool declared by a "management agent" using DM cannot be itself parallel.
-        if (Executor.class.getName().equals(decl.getName())) {
-            Dictionary<?, ?> props = decl.getServiceProperties();
-            if (props != null) {
-                Object property = props.get(DependencyManager.THREADPOOL);
-                if (property != null && "true".equalsIgnoreCase(property.toString()))
{
-                    return false;
+
+        // A threadpool component declared by a "management agent" using DM API cannot be
itself parallel.
+        String[] services = decl.getServices();
+        if (services != null) {
+            for (String service : services) {
+                if (Executor.class.getName().equals(service)) {
+                    Dictionary<?, ?> props = decl.getServiceProperties();
+                    if (props != null && DependencyManager.THREADPOOL.equals(props.get("target")))
{
+                        return false;
+                    }
                 }
             }
         }



Mime
View raw message