You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pd...@apache.org on 2014/10/07 22:34:16 UTC

svn commit: r1629978 - in /felix/sandbox/pderop/dependencymanager-prototype: org.apache.felix.dependencymanager.shell/src/org/apache/felix/dm/shell/ org.apache.felix.dependencymanager/src/org/apache/felix/dm/ org.apache.felix.dependencymanager/src/org/...

Author: pderop
Date: Tue Oct  7 20:34:15 2014
New Revision: 1629978

URL: http://svn.apache.org/r1629978
Log:
FELIX-4667: "top" command for the Dependency Manager Shell.

Modified:
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.shell/src/org/apache/felix/dm/shell/DMCommand.java
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentDeclaration.java
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentImpl.java
    felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FilterComponent.java

Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.shell/src/org/apache/felix/dm/shell/DMCommand.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.shell/src/org/apache/felix/dm/shell/DMCommand.java?rev=1629978&r1=1629977&r2=1629978&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.shell/src/org/apache/felix/dm/shell/DMCommand.java (original)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager.shell/src/org/apache/felix/dm/shell/DMCommand.java Tue Oct  7 20:34:15 2014
@@ -25,6 +25,7 @@ import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Properties;
 import java.util.Set;
@@ -143,33 +144,37 @@ public class DMCommand {
             boolean wtf,
 
             @Descriptor("Displays components statistics") 
-            @Parameter(names = {"stats", "st"}, presentValue = "true", absentValue = "false") 
+            @Parameter(names = {"stats", "stat", "st"}, presentValue = "true", absentValue = "false") 
             boolean stats,
 
-            @Descriptor("OSGi filter used to filter some service properties") 
+            @Descriptor("<OSGi filter used to filter some service properties>") 
             @Parameter(names = {"services", "s"}, absentValue = "") 
             String services,
 
-            @Descriptor("Regex(s) used to filter on component implementation class names (comma separated, can be negated using \"!\" prefix)") 
+            @Descriptor("<Regex(s) used to filter on component implementation class names (comma separated), can be negated using \"!\" prefix>") 
             @Parameter(names = {"components", "c"}, absentValue = "") 
             String components,
             
-            @Descriptor("Component identifiers to display (list of longs, comma separated)") 
+            @Descriptor("<List of component identifiers to display (comma separated)>") 
             @Parameter(names = {"componentIds", "cid", "ci"}, absentValue = "") 
             String componentIds,
 
-            @Descriptor("List of bundle ids or bundle symbolic names to display (comma separated)") 
-            @Parameter(names = {"bundleIds", "bid", "bi"}, absentValue = "") 
-            String bundleIds) {
+            @Descriptor("<List of bundle ids or bundle symbolic names to display (comma separated)>") 
+            @Parameter(names = {"bundleIds", "bid", "bi", "b"}, absentValue = "") 
+            String bundleIds,
+            
+            @Descriptor("<Max number of top components to display (0=all)> This command displays components callbacks (init/start) times>") 
+            @Parameter(names = {"top"}, absentValue = "-1") 
+            int top)
+        {
         
         try {
             boolean comp = Boolean.parseBoolean(getParam(session, ENV_COMPACT, compact));
             services = getParam(session, ENV_SERVICES, services);
             String[] componentsRegex = getParams(session, ENV_COMPONENTS, components);
-
             ArrayList<String> bids = new ArrayList<String>(); // list of bundle ids or bundle symbolic names
             ArrayList<Long> cids = new ArrayList<Long>(); // list of component ids
-
+            
             // Parse and check componentIds option
             StringTokenizer tok = new StringTokenizer(componentIds, ", ");
             while (tok.hasMoreTokens()) {
@@ -199,6 +204,11 @@ public class DMCommand {
                 bids.add(tok.nextToken());
             }
             
+            if (top != -1) {
+                showTopComponents(top);
+                return;
+            }
+            
             if (wtf) {
                 wtf();
                 return;
@@ -301,6 +311,55 @@ public class DMCommand {
         }
     }
 
+    /**
+     * Displays components callbacks (init/start/stop/destroy) elapsed time.
+     * The components are sorted (the most time consuming components are displayed first).
+     * @param max the max number of components to display (0 means all components)
+     */
+    private void showTopComponents(int max) {
+        List<Component> components = new ArrayList<>();
+        for (DependencyManager manager : DependencyManager.getDependencyManagers()) {
+           components.addAll(manager.getComponents()); 
+        }
+        Collections.sort(components, new Comparator<Component>() {
+            @Override
+            public int compare(Component c1, Component c2) {
+                Map<String, Long> c1Times = c1.getComponentDeclaration().getCallbacksTime();
+                Map<String, Long> c2Times = c2.getComponentDeclaration().getCallbacksTime();
+                Long c1Start = c1Times.get("start");
+                Long c2Start = c2Times.get("start");
+                if (c1Start != null) {
+                    if (c2Start != null) {
+                        return c1Start > c2Start ? 1 : -1;
+                    } else {
+                        return 1;
+                    }
+                } else {
+                    if (c2Start != null) {
+                        return -1;
+                    } else {
+                        return 0;
+                    }
+                }
+            }
+        });
+        
+        Collections.reverse(components);
+
+        System.out.printf("%-100s %10s %10s%n%n", "Top components (sorted by start duration time)", "[init time]", "[start time]");
+        
+        if (components.size() > 0) {
+            System.out.println();
+            
+            max = max == 0 ? components.size() : Math.min(components.size(), max);
+            for (int i = 0 ; i < components.size()  && i < max; i++) {
+                ComponentDeclaration decl = components.get(i).getComponentDeclaration();
+                System.out.printf("%-100s %10d %10d%n", decl.getClassName(),
+                    decl.getCallbacksTime().get("init"), decl.getCallbacksTime().get("start"));
+            }
+        }
+    }
+
     private boolean isUnavailable(ComponentDependencyDeclaration dep) {
         switch (dep.getState()) {
             case ComponentDependencyDeclaration.STATE_UNAVAILABLE_OPTIONAL:

Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentDeclaration.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentDeclaration.java?rev=1629978&r1=1629977&r2=1629978&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentDeclaration.java (original)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentDeclaration.java Tue Oct  7 20:34:15 2014
@@ -19,6 +19,7 @@
 package org.apache.felix.dm;
 
 import java.util.Dictionary;
+import java.util.Map;
 
 import org.osgi.framework.BundleContext;
 
@@ -54,5 +55,7 @@ public interface ComponentDeclaration {
     /** Returns the bundle context associated with this component. */
     public BundleContext getBundleContext();
     /** Returns the dependency manager for this component */
-    public DependencyManager getDependencyManager();    
+    public DependencyManager getDependencyManager();
+    /** Returns the execution time in nanos for each component callbacks (init/start/stop/destroy) */
+    public Map<String, Long> getCallbacksTime(); 
 }

Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentImpl.java?rev=1629978&r1=1629977&r2=1629978&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentImpl.java (original)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentImpl.java Tue Oct  7 20:34:15 2014
@@ -77,6 +77,7 @@ public class ComponentImpl implements Co
     private volatile ServiceRegistration m_registration;
     private final Map<Class<?>, Boolean> m_autoConfig = new ConcurrentHashMap<>();
     private final Map<Class<?>, String> m_autoConfigInstance = new ConcurrentHashMap<>();
+    private final Map<String, Long> m_stopwatch = new ConcurrentHashMap<>();
     private final long m_id;
     private static AtomicLong m_idGenerator = new AtomicLong();
     // Holds all the services of a given dependency context. Caution: the last entry in the skiplist is the highest ranked service.
@@ -860,9 +861,15 @@ public class ComponentImpl implements Co
             // ask the service for its composition instances
             Object[] instances = m_callbackInstance != null ? new Object[] { m_callbackInstance } : getCompositionInstances();
 
-            invokeCallbackMethod(instances, name, 
-                new Class[][] {{ Component.class }, {}}, 
-                new Object[][] {{ this }, {}});
+            long t1 = System.nanoTime();
+            try {
+                invokeCallbackMethod(instances, name, 
+                    new Class[][] {{ Component.class }, {}}, 
+                    new Object[][] {{ this }, {}});
+            } finally {
+                long t2 = System.nanoTime();
+                m_stopwatch.put(name, t2 - t1);
+            }
         }
     }
     
@@ -1227,9 +1234,9 @@ public class ComponentImpl implements Co
     @Override
     public String toString() {
     	if (debug) {
-    		System.out.println(debugKey);
+    		return debugKey;
     	}
-    	return super.toString();
+    	return getClassName();
     }
     
     @Override
@@ -1242,4 +1249,9 @@ public class ComponentImpl implements Co
     public Logger getLogger() {
         return m_logger;
     }
+
+    @Override
+    public Map<String, Long> getCallbacksTime() {
+        return m_stopwatch;
+    }
 }

Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FilterComponent.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FilterComponent.java?rev=1629978&r1=1629977&r2=1629978&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FilterComponent.java (original)
+++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FilterComponent.java Tue Oct  7 20:34:15 2014
@@ -20,6 +20,7 @@ package org.apache.felix.dm.impl;
 
 import java.util.Dictionary;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.Executor;
@@ -337,4 +338,9 @@ public class FilterComponent implements 
         m_component.setThreadPool(threadPool);
         return this;
     }
+
+    @Override
+    public Map<String, Long> getCallbacksTime() {
+        return m_component.getCallbacksTime();
+    }
 }
\ No newline at end of file