This is an automated email from the ASF dual-hosted git repository.

cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/felix-dev.git


The following commit(s) were added to refs/heads/master by this push:
     new 465bb43  FELIX-6399 : Reduce resource consumption during component 
checks
465bb43 is described below

commit 465bb43a9ab9a96d21207d7ab1fc65d9c57d85b1
Author: Carsten Ziegeler <[email protected]>
AuthorDate: Fri Aug 13 11:30:56 2021 +0200

    FELIX-6399 : Reduce resource consumption during component checks
---
 systemready/pom.xml                                | 78 +++++++++++++---------
 .../felix/systemready/impl/ComponentsCheck.java    | 59 ++++++++--------
 .../systemready/impl/SystemReadyMonitorImpl.java   | 52 ++++++++++-----
 .../felix/systemready/osgi/util/BaseTest.java      |  2 +-
 4 files changed, 113 insertions(+), 78 deletions(-)

diff --git a/systemready/pom.xml b/systemready/pom.xml
index 8f5dc25..a874fa5 100644
--- a/systemready/pom.xml
+++ b/systemready/pom.xml
@@ -15,7 +15,7 @@
     <parent>
         <groupId>org.apache.felix</groupId>
         <artifactId>felix-parent</artifactId>
-        <version>6</version>
+        <version>7</version>
         <relativePath />
     </parent>
 
@@ -35,26 +35,12 @@
         <url>http://svn.apache.org/viewvc/felix/trunk/systemready</url>
     </scm>
     
-    <repositories>
-        <repository>
-            <id>apache.snapshots</id>
-            <name>snapshot plugins</name>
-            <url>http://repository.apache.org/snapshots</url>
-            <releases>
-                <enabled>false</enabled>
-            </releases>
-            <snapshots>
-                <enabled>true</enabled>
-            </snapshots>
-        </repository>
-    </repositories>
-
     <build>
         <plugins>
             <plugin>
                 <groupId>biz.aQute.bnd</groupId>
                 <artifactId>bnd-maven-plugin</artifactId>
-                <version>4.0.0</version>
+                <version>5.3.0</version>
                 <executions>
                     <execution>
                         <goals>
@@ -95,37 +81,67 @@
 
 
     <dependencies>
-       <dependency>
-            <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.rootcause</artifactId>
-            <version>0.1.0</version>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi.core</artifactId>
+            <version>7.0.0</version>
+            <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>javax.servlet</groupId>
-            <artifactId>servlet-api</artifactId>
-            <version>2.5</version>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.cm</artifactId>
+            <version>1.6.0</version>
             <scope>provided</scope>
-            <optional>true</optional>
         </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
-            <artifactId>osgi.cmpn</artifactId>
-            <version>6.0.0</version>
+            <artifactId>org.osgi.service.http.whiteboard</artifactId>
+            <version>1.1.0</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.core</artifactId>
-            <version>6.0.0</version>
+            <artifactId>org.osgi.service.component</artifactId>
+            <version>1.4.0</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
-            <artifactId>osgi.annotation</artifactId>
-            <version>7.0.0</version>
+            <artifactId>org.osgi.annotation.versioning</artifactId>
+            <version>1.1.1</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.annotation.bundle</artifactId>
+            <version>1.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+       <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.rootcause</artifactId>
+            <version>0.1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.component.annotations</artifactId>
+            <version>1.4.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.metatype.annotations</artifactId>
+            <version>1.4.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.5</version>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
             <version>1.7.6</version>
@@ -190,7 +206,7 @@
         <dependency>
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.framework</artifactId>
-            <version>5.6.10</version>
+            <version>6.0.5</version>
             <scope>test</scope>
         </dependency>
  
diff --git 
a/systemready/src/main/java/org/apache/felix/systemready/impl/ComponentsCheck.java
 
b/systemready/src/main/java/org/apache/felix/systemready/impl/ComponentsCheck.java
index 85ce5e6..b4f794a 100644
--- 
a/systemready/src/main/java/org/apache/felix/systemready/impl/ComponentsCheck.java
+++ 
b/systemready/src/main/java/org/apache/felix/systemready/impl/ComponentsCheck.java
@@ -31,10 +31,11 @@ import org.apache.felix.rootcause.RootCausePrinter;
 import org.apache.felix.systemready.CheckStatus;
 import org.apache.felix.systemready.StateType;
 import org.apache.felix.systemready.SystemReadyCheck;
+import org.osgi.framework.AllServiceListener;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationListener;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.ConfigurationPolicy;
@@ -49,15 +50,17 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Component(
-        service = {SystemReadyCheck.class},
+        service = {SystemReadyCheck.class, ConfigurationListener.class},
         name = ComponentsCheck.PID,
         configurationPolicy = ConfigurationPolicy.REQUIRE
 )
 @Designate(ocd=ComponentsCheck.Config.class)
-public class ComponentsCheck implements SystemReadyCheck, ServiceListener {
+public class ComponentsCheck implements SystemReadyCheck, AllServiceListener, 
ConfigurationListener {
 
     public static final String PID = 
"org.apache.felix.systemready.impl.ComponentsCheck";
 
+    private static final CheckStatus INVALID = new CheckStatus("invalid", 
StateType.READY, CheckStatus.State.RED, "invalid");
+
     @ObjectClassDefinition(
             name="DS Components System Ready Check",
             description="System ready check that checks a list of DS 
components"
@@ -74,36 +77,38 @@ public class ComponentsCheck implements SystemReadyCheck, 
ServiceListener {
     }
     private final Logger log = LoggerFactory.getLogger(getClass());
 
-    private List<String> componentsList;
+    private final List<String> componentsList;
 
-    private DSRootCause analyzer;
+    private final DSRootCause analyzer;
 
-    private StateType type;
+    private final StateType type;
 
-    @Reference
-    private ServiceComponentRuntime scr;
+    private final ServiceComponentRuntime scr;
 
     private final AtomicReference<CheckStatus> cache = new AtomicReference<>();
 
-    private static final CheckStatus INVALID = new CheckStatus("invalid", 
StateType.READY, CheckStatus.State.RED, "invalid");
-
     @Activate
-    public void activate(final BundleContext ctx, final Config config) throws 
InterruptedException, InvalidSyntaxException {
+    public ComponentsCheck(final BundleContext ctx, final Config config, final 
@Reference ServiceComponentRuntime scr) throws InterruptedException {
         this.analyzer = new DSRootCause(scr);
         this.type = config.type();
         this.componentsList = Arrays.asList(config.components_list());
         this.cache.set(INVALID);
-//        ctx.addServiceListener(this, "(objectClass=" + 
ServiceComponentRuntime.class.getName() + ")");
+        this.scr = scr;
+        ctx.addServiceListener(this);
     }
 
     @Deactivate
     public void deactivate(final BundleContext ctx) {
-//        ctx.removeServiceListener(this);
+        ctx.removeServiceListener(this);
     }
 
     @Override
-    public void serviceChanged(ServiceEvent event) {
-//        log.info("CALLED");
+    public void serviceChanged(final ServiceEvent event) {
+        this.cache.set(INVALID);
+    }
+
+    @Override
+    public void configurationEvent(final ConfigurationEvent event) {
         this.cache.set(INVALID);
     }
 
@@ -127,22 +132,17 @@ public class ComponentsCheck implements SystemReadyCheck, 
ServiceListener {
     @Override
     public CheckStatus getStatus() {
         CheckStatus result = null;
-/*
-        while ( result == null )
-        {
+
+        while ( result == null ) {
             this.cache.compareAndSet(INVALID, null);
             result = this.cache.get();
-            if ( result == INVALID )
-            {
+            if ( result == INVALID ) {
                 result = null; // repeat
-            }
-            else if ( result == null )
-            {
-*/                final List<DSComp> watchedComps = 
getComponents(scr.getComponentDescriptionDTOs());
+            } else if ( result == null ) {
+                final List<DSComp> watchedComps = 
getComponents(scr.getComponentDescriptionDTOs());
                 if (watchedComps.size() < componentsList.size()) {
                     final List<String> missed = new 
ArrayList<>(this.componentsList);
-                    for(final DSComp c : watchedComps)
-                    {
+                    for(final DSComp c : watchedComps) {
                         missed.remove(c.desc.name);
                     }
                     result = new CheckStatus(getName(), type, 
CheckStatus.State.RED, "Not all named components could be found, missing : " + 
missed);
@@ -157,13 +157,12 @@ public class ComponentsCheck implements SystemReadyCheck, 
ServiceListener {
                         throw e;
                     }
                 }
-/*                if ( !this.cache.compareAndSet(null, result) )
-                {
+                if ( !this.cache.compareAndSet(null, result) ) {
                     result = null;
                 }
             }
         }
-*/        return result;
+        return result;
      }
 
     private CheckStatus.State status(DSComp component) {
diff --git 
a/systemready/src/main/java/org/apache/felix/systemready/impl/SystemReadyMonitorImpl.java
 
b/systemready/src/main/java/org/apache/felix/systemready/impl/SystemReadyMonitorImpl.java
index 63084a4..f7b5fc2 100644
--- 
a/systemready/src/main/java/org/apache/felix/systemready/impl/SystemReadyMonitorImpl.java
+++ 
b/systemready/src/main/java/org/apache/felix/systemready/impl/SystemReadyMonitorImpl.java
@@ -22,7 +22,9 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -72,7 +74,7 @@ public class SystemReadyMonitorImpl implements 
SystemReadyMonitor {
     @Reference(policy = ReferencePolicy.DYNAMIC)
     private volatile List<SystemReadyCheck> checks;
 
-    private BundleContext context;
+    private final BundleContext context;
 
     private final AtomicReference<ServiceRegistration<SystemReady>> sreg = new 
AtomicReference<>();
 
@@ -80,17 +82,16 @@ public class SystemReadyMonitorImpl implements 
SystemReadyMonitor {
 
     private final AtomicReference<Collection<CheckStatus>> curStates;
 
-    public SystemReadyMonitorImpl() {
-       CheckStatus checkStatus = new CheckStatus("dummy", StateType.READY, 
State.YELLOW, "");
-        this.curStates = new 
AtomicReference<>(Collections.singleton(checkStatus));
-    }
+    private final Map<String, String> errorMsgs = new HashMap<>();
 
     @Activate
-    public void activate(BundleContext context, final Config config) {
+    public SystemReadyMonitorImpl(BundleContext context, final Config config) {
+        CheckStatus checkStatus = new CheckStatus("dummy", StateType.READY, 
State.YELLOW, "");
+        this.curStates = new 
AtomicReference<>(Collections.singleton(checkStatus));
         this.context = context;
         this.executor.set(Executors.newSingleThreadScheduledExecutor());
         this.executor.get().scheduleAtFixedRate(this::check, 0, 
config.poll_interval(), TimeUnit.MILLISECONDS);
-        log.info("Activated. Running checks every {} ms.", 
config.poll_interval());
+        this.log.info("Activated. Running checks every {} ms.", 
config.poll_interval());
     }
 
     @Deactivate
@@ -101,15 +102,15 @@ public class SystemReadyMonitorImpl implements 
SystemReadyMonitor {
         if ( reg != null ) {
             reg.unregister();
         }
-        log.info("Deactivated.");
+        this.log.info("Deactivated.");
     }
 
     @Override
     /**
      * Returns a map of the statuses of all the checks
      */
-    public SystemStatus getStatus(StateType stateType) {
-       Collection<CheckStatus> filtered = stateType == StateType.READY ? 
curStates.get() :
+    public SystemStatus getStatus(final StateType stateType) {
+       final Collection<CheckStatus> filtered = stateType == StateType.READY ? 
curStates.get() :
                curStates.get().stream()
                        .filter(status -> status.getType() == 
StateType.ALIVE).collect(Collectors.toList());
         return new SystemStatus(filtered);
@@ -117,11 +118,15 @@ public class SystemReadyMonitorImpl implements 
SystemReadyMonitor {
 
     private void check() {
         try {
-            CheckStatus.State prevState = 
getStatus(StateType.READY).getState();
-            List<SystemReadyCheck> currentChecks = new ArrayList<>(checks);
-            List<String> checkNames = currentChecks.stream().map(check -> 
check.getName()).collect(Collectors.toList());
-            log.debug("Running system checks {}", checkNames);
-            List<CheckStatus> statuses = evaluateAllChecks(currentChecks);
+            final CheckStatus.State prevState = 
getStatus(StateType.READY).getState();
+
+            final List<SystemReadyCheck> currentChecks = new 
ArrayList<>(checks);
+            final List<String> checkNames = currentChecks.stream().map(check 
-> check.getName()).collect(Collectors.toList());
+
+            this.log.debug("Running system checks {}", checkNames);
+
+            final List<CheckStatus> statuses = 
evaluateAllChecks(currentChecks);
+
             this.curStates.set(statuses);
             State currState = getStatus(StateType.READY).getState();
             if (currState != prevState) {
@@ -130,6 +135,7 @@ public class SystemReadyMonitorImpl implements 
SystemReadyMonitor {
             log.debug("Checks finished");
         } catch (Exception e) {
             log.warn("Exception when running checks", e);
+            this.errorMsgs.clear();
         }
     }
 
@@ -155,14 +161,28 @@ public class SystemReadyMonitorImpl implements 
SystemReadyMonitor {
         }
     }
 
+    /**
+     * Execute a single check
+     * @param c The check
+     * @return Return the status
+     */
     private final CheckStatus getStatus(final SystemReadyCheck c) {
         try {
             final CheckStatus status = c.getStatus();
             if ( status.getState() != State.GREEN ) {
-                log.info("Executing systemready checked {} returned {}", 
c.getName(), status);
+                final String msg = status.toString();
+                if ( !msg.equals(this.errorMsgs.get(c.getName())) ) {
+                    this.errorMsgs.put(c.getName(), msg);
+                    log.info("Executing systemready check {} returned {}", 
c.getName(), msg);
+                }
+            } else {
+                if ( this.errorMsgs.remove(c.getName()) != null ) {
+                    log.info("Executing systemready check {} back to GREEN", 
c.getName());
+                }
             }
             return status;
         } catch (final Throwable e) {
+            this.errorMsgs.remove(c.getName());
             log.error("Exception while executing systemready check {} : {}", 
c.getClass().getName(), e.getMessage(), e);
             return new CheckStatus(c.getName(), StateType.READY, 
CheckStatus.State.RED, e.getMessage());
         }
diff --git 
a/systemready/src/test/java/org/apache/felix/systemready/osgi/util/BaseTest.java
 
b/systemready/src/test/java/org/apache/felix/systemready/osgi/util/BaseTest.java
index 1ed4d97..9a827e6 100644
--- 
a/systemready/src/test/java/org/apache/felix/systemready/osgi/util/BaseTest.java
+++ 
b/systemready/src/test/java/org/apache/felix/systemready/osgi/util/BaseTest.java
@@ -115,7 +115,7 @@ public class BaseTest {
     public Option httpService() {
         return CoreOptions.composite(
                 mavenBundle("org.apache.felix", 
"org.apache.felix.http.servlet-api", "1.1.2"),
-                mavenBundle("org.apache.felix", "org.apache.felix.http.jetty", 
"3.4.8")
+                mavenBundle("org.apache.felix", "org.apache.felix.http.jetty", 
"4.1.10")
                 );
     }
 

Reply via email to