incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bdelacre...@apache.org
Subject svn commit: r793010 - in /sling/trunk/contrib/extensions/jcrinstall: it/src/test/java/org/apache/sling/jcr/jcrinstall/it/ osgi/src/main/java/org/apache/sling/osgi/installer/ osgi/src/main/java/org/apache/sling/osgi/installer/impl/ osgi/src/main/java/or...
Date Fri, 10 Jul 2009 16:21:26 GMT
Author: bdelacretaz
Date: Fri Jul 10 16:21:25 2009
New Revision: 793010

URL: http://svn.apache.org/viewvc?rev=793010&view=rev
Log:
SLING-1042 - Optimize jcrinstall retry cycles

Added:
    sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/OsgiControllerStatistics.java
  (with props)
    sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/EventsCounter.java
  (with props)
    sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/EventsCounterImpl.java
  (with props)
Modified:
    sling/trunk/contrib/extensions/jcrinstall/it/src/test/java/org/apache/sling/jcr/jcrinstall/it/OsgiControllerTest.java
    sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/Activator.java
    sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerImpl.java
    sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerTask.java
    sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleStartTask.java

Modified: sling/trunk/contrib/extensions/jcrinstall/it/src/test/java/org/apache/sling/jcr/jcrinstall/it/OsgiControllerTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/it/src/test/java/org/apache/sling/jcr/jcrinstall/it/OsgiControllerTest.java?rev=793010&r1=793009&r2=793010&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/jcrinstall/it/src/test/java/org/apache/sling/jcr/jcrinstall/it/OsgiControllerTest.java
(original)
+++ sling/trunk/contrib/extensions/jcrinstall/it/src/test/java/org/apache/sling/jcr/jcrinstall/it/OsgiControllerTest.java
Fri Jul 10 16:21:25 2009
@@ -30,12 +30,15 @@
 import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption;
 
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
 import java.util.Dictionary;
 import java.util.Hashtable;
 
 import org.apache.sling.osgi.installer.DictionaryInstallableData;
 import org.apache.sling.osgi.installer.OsgiController;
 import org.apache.sling.osgi.installer.OsgiControllerServices;
+import org.apache.sling.osgi.installer.OsgiControllerStatistics;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.ops4j.pax.exam.Inject;
@@ -43,9 +46,12 @@
 import org.ops4j.pax.exam.junit.JUnit4TestRunner;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.cm.Configuration;
 import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.packageadmin.PackageAdmin;
 
 /** Test the OsgiController running in the OSGi framework
  *  
@@ -55,9 +61,10 @@
  *   
  */
 @RunWith(JUnit4TestRunner.class)
-public class OsgiControllerTest {
+public class OsgiControllerTest implements FrameworkListener {
 	public final static String POM_VERSION = System.getProperty("jcrinstall.pom.version");
 	public final static String JAR_EXT = ".jar";
+	private int packageRefreshEventsCount;
 	
     @Inject
     protected BundleContext bundleContext;
@@ -71,6 +78,61 @@
     	return result;
     }
     
+    protected void generateBundleEvent() throws Exception {
+        // install a bundle manually to generate a bundle event
+        final File f = getTestBundle("org.apache.sling.jcr.jcrinstall.it-" + POM_VERSION
+ "-testbundle-1.0.jar");
+        final InputStream is = new FileInputStream(f);
+        Bundle b = null;
+        try {
+            b = bundleContext.installBundle(getClass().getName(), is);
+            b.start();
+            final long timeout = System.currentTimeMillis() + 2000L;
+            while(b.getState() != Bundle.ACTIVE && System.currentTimeMillis() <
timeout) {
+                Thread.sleep(10L);
+            }
+        } finally {
+            if(is != null) {
+                is.close();
+            }
+            if(b != null) {
+                b.uninstall();
+            }
+        }
+    }
+    
+    public void frameworkEvent(FrameworkEvent event) {
+        if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) {
+            packageRefreshEventsCount++;
+        }
+    }
+    
+    protected void refreshPackages() {
+        bundleContext.addFrameworkListener(this);
+        final int MAX_REFRESH_PACKAGES_WAIT_SECONDS = 5;
+        final int targetEventCount = packageRefreshEventsCount + 1;
+        final long timeout = System.currentTimeMillis() + MAX_REFRESH_PACKAGES_WAIT_SECONDS
* 1000L;
+        
+        final PackageAdmin pa = getService(PackageAdmin.class);
+        pa.refreshPackages(null);
+        
+        try {
+            while(true) {
+                if(System.currentTimeMillis() > timeout) {
+                    break;
+                }
+                if(packageRefreshEventsCount >= targetEventCount) {
+                    break;
+                }
+                try {
+                    Thread.sleep(250L);
+                } catch(InterruptedException ignore) {
+                }
+            }
+        } finally {
+            bundleContext.removeFrameworkListener(this);
+        }
+    }
+    
     protected Configuration findConfiguration(String pid) throws Exception {
     	final ConfigurationAdmin ca = getService(ConfigurationAdmin.class);
     	if(ca != null) {
@@ -311,6 +373,50 @@
         	assertFalse(needsB + " must not be started, testB not present", b.getState() ==
Bundle.ACTIVE);
     	}
     	
+    	// Check SLING-1042 retry rules
+    	assertTrue("OsgiController must implement OsgiControllerStatistics", c instanceof OsgiControllerStatistics);
+    	final OsgiControllerStatistics stats = (OsgiControllerStatistics)c;
+    	
+    	{
+    	    long n = stats.getExecutedTasksCount();
+    	    c.executeScheduledOperations();
+            assertTrue("First retry must not wait for an event", stats.getExecutedTasksCount()
> n);
+            n = stats.getExecutedTasksCount();
+            c.executeScheduledOperations();
+    	    assertEquals("Retrying before a bundle event happens must not execute any OsgiControllerTask",
n, stats.getExecutedTasksCount());
+    	    
+            n = stats.getExecutedTasksCount();
+    	    generateBundleEvent();
+            c.executeScheduledOperations();
+            assertTrue("Retrying after a bundle event must execute at least one OsgiControllerTask",
stats.getExecutedTasksCount() > n);
+    	}
+    	
+    	{
+    	    // wait until no more events are received
+            final long timeout = System.currentTimeMillis() + 2000L;
+            while(System.currentTimeMillis() < timeout) {
+                final long n = stats.getExecutedTasksCount();
+                c.executeScheduledOperations();
+                if(n == stats.getExecutedTasksCount()) {
+                    break;
+                }
+                Thread.sleep(10L);
+            }
+            
+            if(System.currentTimeMillis() >= timeout) {
+                fail("Retries did not stop within specified time");
+            }
+    	}
+    	
+        {
+            long n = stats.getExecutedTasksCount();
+            c.executeScheduledOperations();
+            assertEquals("Retrying before a framework event happens must not execute any
OsgiControllerTask", n, stats.getExecutedTasksCount());
+            refreshPackages();
+            c.executeScheduledOperations();
+            assertTrue("Retrying after framework event must execute at least one OsgiControllerTask",
stats.getExecutedTasksCount() > n);
+        }
+        
     	// now install testB -> needsB must start
     	{
         	c.scheduleInstallOrUpdate(testB + JAR_EXT,

Added: sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/OsgiControllerStatistics.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/OsgiControllerStatistics.java?rev=793010&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/OsgiControllerStatistics.java
(added)
+++ sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/OsgiControllerStatistics.java
Fri Jul 10 16:21:25 2009
@@ -0,0 +1,25 @@
+/*
+ * 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.osgi.installer;
+
+/** Statistics for the OsgiController */
+public interface OsgiControllerStatistics {
+    /** How many OsgiControllerTask the controller tried to execute */
+    long getExecutedTasksCount();
+}

Propchange: sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/OsgiControllerStatistics.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/OsgiControllerStatistics.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/Activator.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/Activator.java?rev=793010&r1=793009&r2=793010&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/Activator.java
(original)
+++ sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/Activator.java
Fri Jul 10 16:21:25 2009
@@ -39,14 +39,12 @@
     private static String LOG_SERVICE_NAME = LogService.class.getName();
 
     private ServiceTracker startLevelTracker;
-
     private ServiceTracker packageAdminTracker;
-
     private ServiceTracker logServiceTracker;
-
-    private OsgiControllerImpl service;
-
-    private ServiceRegistration serviceReg;
+    private OsgiControllerImpl osgiControllerService;
+    private ServiceRegistration osgiControllerServiceReg;
+    private EventsCounterImpl eventsCounter;
+    private ServiceRegistration eventsCounterServiceReg;
 
     /**
      * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
@@ -59,21 +57,36 @@
         this.packageAdminTracker.open();
         this.logServiceTracker.open();
 
-        // register service
-        final Hashtable<String, String> props = new Hashtable<String, String>();
-        props.put(Constants.SERVICE_DESCRIPTION, "Apache Sling Install Controller Service");
-        props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+        // register OsgiController service        
+        {
+            final Hashtable<String, String> props = new Hashtable<String, String>();
+            props.put(Constants.SERVICE_DESCRIPTION, "Apache Sling Install Controller Service");
+            props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+            
+            // Assume PackageAdmin is available before this bundle is started.
+            // That's the case when using Felix OSGi, not sure about other frameworks.
+            this.osgiControllerService = new OsgiControllerImpl(context,
+                    (PackageAdmin)checkNotNull(this.packageAdminTracker.getService(), "PackageAdmin"),
+                    logServiceTracker);
+            final String [] serviceInterfaces = {
+                    OsgiController.class.getName(),
+                    OsgiControllerServices.class.getName()
+            };
+            osgiControllerServiceReg = context.registerService(serviceInterfaces, osgiControllerService,
props);
+        }
         
-        // Assume PackageAdmin is available before this bundle is started.
-        // That's the case when using Felix OSGi, not sure about other frameworks.
-        this.service = new OsgiControllerImpl(context,
-                (PackageAdmin)checkNotNull(this.packageAdminTracker.getService(), "PackageAdmin"),
-                logServiceTracker);
-        final String [] serviceInterfaces = {
-        		OsgiController.class.getName(),
-        		OsgiControllerServices.class.getName()
-        };
-        serviceReg = context.registerService(serviceInterfaces, service, props);
+        // register EventsCounter service        
+        {
+            final Hashtable<String, String> props = new Hashtable<String, String>();
+            props.put(Constants.SERVICE_DESCRIPTION, "Apache Sling EventsCounter Service");
+            props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+            
+            this.eventsCounter = new EventsCounterImpl(context);
+            final String [] serviceInterfaces = {
+                    EventsCounter.class.getName()
+            };
+            eventsCounterServiceReg = context.registerService(serviceInterfaces, eventsCounter,
props);
+        }
     }
     
     /** Complain if value is null */
@@ -88,13 +101,21 @@
      * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
      */
     public void stop(BundleContext context) throws Exception {
-        if ( this.serviceReg != null ) {
-            this.serviceReg.unregister();
-            this.serviceReg = null;
-        }
-        if ( this.service != null ) {
-            this.service.deactivate();
-            this.service = null;
+        if( this.eventsCounterServiceReg != null) {
+            this.eventsCounterServiceReg.unregister();
+            this.eventsCounterServiceReg = null;
+        }
+        if( this.eventsCounter != null) {
+            this.eventsCounter.deactivate();
+            this.eventsCounter = null;
+        }
+        if ( this.osgiControllerServiceReg != null ) {
+            this.osgiControllerServiceReg.unregister();
+            this.osgiControllerServiceReg = null;
+        }
+        if ( this.osgiControllerService != null ) {
+            this.osgiControllerService.deactivate();
+            this.osgiControllerService = null;
         }
         if ( this.startLevelTracker != null ) {
             this.startLevelTracker.close();

Added: sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/EventsCounter.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/EventsCounter.java?rev=793010&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/EventsCounter.java
(added)
+++ sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/EventsCounter.java
Fri Jul 10 16:21:25 2009
@@ -0,0 +1,24 @@
+/*
+ * 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.osgi.installer.impl;
+
+/** Count framework + bundle events - used for SLING-1042 retries optimization */
+public interface EventsCounter {
+    long getTotalEventsCount();
+}

Propchange: sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/EventsCounter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/EventsCounter.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/EventsCounterImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/EventsCounterImpl.java?rev=793010&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/EventsCounterImpl.java
(added)
+++ sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/EventsCounterImpl.java
Fri Jul 10 16:21:25 2009
@@ -0,0 +1,59 @@
+/*
+ * 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.osgi.installer.impl;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+
+/** EventsCounter implementation - simply counts events,
+ *  to avoid having to make each BundleStartTask that's
+ *  waiting for retries a FrameworkListener and BundleListener 
+ */
+class EventsCounterImpl implements EventsCounter, FrameworkListener, BundleListener {
+    private long eventsCount;
+    private final BundleContext bundleContext;
+    
+    EventsCounterImpl(BundleContext bc) {
+        this.bundleContext = bc;
+        bundleContext.addBundleListener(this);
+        bundleContext.addFrameworkListener(this);
+    }
+    
+    void deactivate() {
+        bundleContext.removeBundleListener(this);
+        bundleContext.removeFrameworkListener(this);
+    }
+    
+    public long getTotalEventsCount() {
+        return eventsCount;
+    }
+
+    public void frameworkEvent(FrameworkEvent arg0) {
+        // we'll retry as soon as any FrameworkEvent or BundleEvent happens
+        eventsCount++;
+    }
+
+    public void bundleChanged(BundleEvent arg0) {
+        // we'll retry as soon as any FrameworkEvent or BundleEvent happens
+        eventsCount++;
+    }
+}

Propchange: sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/EventsCounterImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/EventsCounterImpl.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerImpl.java?rev=793010&r1=793009&r2=793010&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerImpl.java
(original)
+++ sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerImpl.java
Fri Jul 10 16:21:25 2009
@@ -29,6 +29,7 @@
 import org.apache.sling.osgi.installer.JcrInstallException;
 import org.apache.sling.osgi.installer.OsgiController;
 import org.apache.sling.osgi.installer.OsgiControllerServices;
+import org.apache.sling.osgi.installer.OsgiControllerStatistics;
 import org.apache.sling.osgi.installer.ResourceOverrideRules;
 import org.apache.sling.osgi.installer.impl.tasks.BundleInstallRemoveTask;
 import org.apache.sling.osgi.installer.impl.tasks.ConfigInstallRemoveTask;
@@ -46,7 +47,8 @@
 public class OsgiControllerImpl
     implements OsgiController,
                OsgiControllerServices,
-               OsgiControllerTaskContext {
+               OsgiControllerTaskContext,
+               OsgiControllerStatistics {
 
 	private final BundleContext bundleContext;
     private final Storage storage;
@@ -59,6 +61,7 @@
     private final ServiceTracker logServiceTracker;
     private int threadCounter;
     private final PackageAdmin packageAdmin;
+    private int executedTasksCount;
 
     public static final String BUNDLE_EXTENSION = ".jar";
     public static final String STORAGE_FILENAME = "controller.storage";
@@ -144,9 +147,28 @@
         if(tasks.isEmpty()) {
         	return;
         }
-
+        
+        // No executable tasks?
+        boolean exec = false;
+        synchronized (tasks) {
+            for(OsgiControllerTask t : tasks) {
+                if(t.isExecutable(this)) {
+                    exec = true;
+                    break;
+                }
+            }
+        }
+        
     	if(getLogService() != null) {
-    		getLogService().log(LogService.LOG_INFO, "executeScheduledOperations() starts");
+    	    if(exec) {
+                getLogService().log(LogService.LOG_INFO, "executeScheduledOperations() starts");
+    	    } else {
+                getLogService().log(LogService.LOG_DEBUG, "No executable tasks, nothing to
do");
+    	    }
+    	}
+    	
+    	if(!exec) {
+    	    return;
     	}
     	
         synchronized (tasks) {
@@ -199,6 +221,7 @@
 					final List<OsgiControllerTask> toRemove = new LinkedList<OsgiControllerTask>();
 					for(OsgiControllerTask t : tasks) {
 						toRemove.add(t);
+						executedTasksCount++;
 						executeTask(t);
 						if(!tasksForThisCycle.isEmpty()) {
 							break;
@@ -272,4 +295,7 @@
 		return this;
 	}
 
+	public long getExecutedTasksCount() {
+	    return executedTasksCount;
+	}
 }
\ No newline at end of file

Modified: sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerTask.java?rev=793010&r1=793009&r2=793010&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerTask.java
(original)
+++ sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/OsgiControllerTask.java
Fri Jul 10 16:21:25 2009
@@ -26,9 +26,15 @@
 	/** Tasks are sorted according to this key */
 	public abstract String getSortKey();
 
+	/** All comparisons are based on getSortKey() */
 	public final int compareTo(OsgiControllerTask o) {
 		return getSortKey().compareTo(o.getSortKey());
 	}
+	
+	/** Is it worth executing this task now? */
+	public boolean isExecutable(OsgiControllerTaskContext ctx) throws Exception {
+	    return true;
+	}
 
 	@Override
 	public final boolean equals(Object o) {

Modified: sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleStartTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleStartTask.java?rev=793010&r1=793009&r2=793010&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleStartTask.java
(original)
+++ sling/trunk/contrib/extensions/jcrinstall/osgi/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleStartTask.java
Fri Jul 10 16:21:25 2009
@@ -20,10 +20,14 @@
 
 import java.text.DecimalFormat;
 
+import org.apache.sling.osgi.installer.JcrInstallException;
+import org.apache.sling.osgi.installer.impl.EventsCounter;
 import org.apache.sling.osgi.installer.impl.OsgiControllerTask;
 import org.apache.sling.osgi.installer.impl.OsgiControllerTaskContext;
 import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
+import org.osgi.framework.ServiceReference;
 import org.osgi.service.log.LogService;
 
 /** Task that starts a bundle */
@@ -31,6 +35,8 @@
 
 	private final long bundleId;
 	private final String sortKey;
+	private long eventsCountForRetrying;
+	private int retryCount = 0;
 	
 	public BundleStartTask(long bundleId) {
 		this.bundleId = bundleId;
@@ -50,6 +56,7 @@
 	public void execute(OsgiControllerTaskContext tctx) throws Exception {
 		final Bundle b = tctx.getBundleContext().getBundle(bundleId);
 		final LogService log = tctx.getOsgiControllerServices().getLogService();
+		boolean needToRetry = false;
 		
 		if(b == null) {
 			if(log != null) {
@@ -58,24 +65,70 @@
 			return;
 		}
 		
-		if(b.getState() == Bundle.ACTIVE) {
-			if(log != null) {
-				log.log(LogService.LOG_DEBUG, "Bundle already started, no action taken:" + bundleId +
"/" + b.getSymbolicName());
-			}
-		} else {
-			try {
-				b.start();
-				if(log != null) {
-					log.log(LogService.LOG_INFO, "Bundle started:" + bundleId + "/" + b.getSymbolicName());
-				}
-			} catch(BundleException e) {
-				if(log != null) {
-					log.log(LogService.LOG_INFO, 
-							"Could not start bundle (" + e + "), will retry: " + bundleId + "/" + b.getSymbolicName());
-				}
-				tctx.addTaskToNextCycle(this);
-			}
-			
+		try {
+	        if(b.getState() == Bundle.ACTIVE) {
+	            if(log != null) {
+	                log.log(LogService.LOG_DEBUG, "Bundle already started, no action taken:"
+ bundleId + "/" + b.getSymbolicName());
+	            }
+	        } else {
+	            // Try to start bundle, and if that doesn't work we'll need to retry
+	            try {
+	                b.start();
+	                if(log != null) {
+	                    log.log(LogService.LOG_INFO, 
+	                            "Bundle started (retry count=" + retryCount + ", bundle ID="
+ bundleId + ") " + b.getSymbolicName());
+	                }
+	            } catch(BundleException e) {
+	                if(log != null) {
+	                    log.log(LogService.LOG_INFO, 
+	                            "Could not start bundle (retry count=" + retryCount + ", " +
e 
+	                            + "), will retry: " + bundleId + "/" + b.getSymbolicName());
+	                }
+	                needToRetry = true;
+	            }
+	            
+	        }
+		} finally {
+	        if(needToRetry) {
+	            
+	            // Do the first retry immediately (in case "something" happenened right now
+	            // that warrants a retry), but for the next ones wait for at least one bundle
+	            // event or framework event
+	            if(retryCount == 0) {
+	                eventsCountForRetrying = getEventsCount(tctx.getBundleContext());
+	            } else {
+                    eventsCountForRetrying = getEventsCount(tctx.getBundleContext()) + 1;
+	            }
+	            
+	            tctx.addTaskToNextCycle(this);
+	        }
 		}
+		retryCount++;
 	}
+	
+	/** Do not execute this task if waiting for events */
+    public boolean isExecutable(OsgiControllerTaskContext tctx) throws JcrInstallException
{
+        final long eventsCount = getEventsCount(tctx.getBundleContext()); 
+        final boolean result = eventsCount >= eventsCountForRetrying; 
+        if(!result) {
+            if(tctx.getOsgiControllerServices().getLogService() != null) {
+                tctx.getOsgiControllerServices().getLogService().log(LogService.LOG_DEBUG,

+                        this + " is not executable at this time, counters=" + eventsCountForRetrying
+ "/" + eventsCount);
+            }
+        }
+        return result;
+    }
+    
+    /** Return current events count */
+    protected long getEventsCount(BundleContext bc) throws JcrInstallException {
+        final ServiceReference sr = bc.getServiceReference(EventsCounter.class.getName());
+        if(sr == null) {
+            throw new JcrInstallException("EventsCounter service not found");
+        }
+        final EventsCounter ec = (EventsCounter)bc.getService(sr);
+        if(ec == null) {
+            throw new JcrInstallException("EventsCounter service not found, although its
ServiceReference was found");
+        }
+        return ec.getTotalEventsCount();
+    }
 }



Mime
View raw message