You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by st...@apache.org on 2016/03/29 17:42:41 UTC

svn commit: r1737012 - in /sling/trunk/bundles/extensions/event: ./ src/main/java/org/apache/sling/event/impl/jobs/config/ src/test/java/org/apache/sling/event/impl/jobs/config/ src/test/java/org/apache/sling/event/it/

Author: stefanegli
Date: Tue Mar 29 15:42:41 2016
New Revision: 1737012

URL: http://svn.apache.org/viewvc?rev=1737012&view=rev
Log:
SLING-5560 : added 'startup.delay' config param to job manager with a default of 30sec, which helps avoiding unnecessary reassignment of jobs on a cluster restart - ITs adjusted to have a 1sec delay only

Modified:
    sling/trunk/bundles/extensions/event/pom.xml
    sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java
    sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/config/JobManagerConfigurationTest.java
    sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/it/AbstractJobHandlingTest.java

Modified: sling/trunk/bundles/extensions/event/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/pom.xml?rev=1737012&r1=1737011&r2=1737012&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/pom.xml (original)
+++ sling/trunk/bundles/extensions/event/pom.xml Tue Mar 29 15:42:41 2016
@@ -318,7 +318,7 @@
 
         <dependency>
             <groupId>org.ops4j.pax.exam</groupId>
-            <artifactId>pax-exam-container-native</artifactId>
+            <artifactId>pax-exam-container-forked</artifactId>
             <version>${exam.version}</version>
             <scope>test</scope>
         </dependency>
@@ -356,5 +356,11 @@
             <version>1</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+        	<groupId>org.apache.sling</groupId>
+        	<artifactId>org.apache.sling.discovery.commons</artifactId>
+        	<version>1.0.12</version>
+        	<scope>provided</scope>
+        </dependency>
     </dependencies>
 </project>

Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java?rev=1737012&r1=1737011&r2=1737012&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java Tue Mar 29 15:42:41 2016
@@ -42,6 +42,8 @@ import org.apache.sling.api.resource.Res
 import org.apache.sling.commons.osgi.PropertiesUtil;
 import org.apache.sling.commons.scheduler.Scheduler;
 import org.apache.sling.discovery.TopologyEvent;
+import org.apache.sling.discovery.TopologyEventListener;
+import org.apache.sling.discovery.commons.InitDelayingTopologyEventListener;
 import org.apache.sling.discovery.TopologyEvent.Type;
 import org.apache.sling.event.impl.EnvironmentComponent;
 import org.apache.sling.event.impl.jobs.Utility;
@@ -73,6 +75,11 @@ import org.slf4j.LoggerFactory;
               boolValue=JobManagerConfiguration.DEFAULT_LOG_DEPRECATION_WARNINGS,
               label="Deprecation Warnings",
               description="If this switch is enabled, deprecation warnings will be logged with the INFO level."),
+    @Property(name=JobManagerConfiguration.PROPERTY_STARTUP_DELAY,
+              longValue=JobManagerConfiguration.DEFAULT_STARTUP_DELAY,
+              label="Startup Delay",
+              description="Specify amount in seconds that job manager waits on startup before starting with job handling. "
+                        + "This can be used to allow enough time to restart a cluster before jobs are eventually reassigned."),
     @Property(name=JobManagerConfiguration.PROPERTY_REPOSITORY_PATH,
               value=JobManagerConfiguration.DEFAULT_REPOSITORY_PATH, propertyPrivate=true),
     @Property(name=JobManagerConfiguration.PROPERTY_SCHEDULED_JOBS_PATH,
@@ -94,6 +101,9 @@ public class JobManagerConfiguration {
     /** Default background load delay. */
     public static final long DEFAULT_BACKGROUND_LOAD_DELAY = 10;
 
+    /** Default startup delay. */
+    public static final long DEFAULT_STARTUP_DELAY = 30;
+    
     /** Default for disabling the distribution. */
     public static final boolean DEFAULT_DISABLE_DISTRIBUTION = false;
 
@@ -106,6 +116,9 @@ public class JobManagerConfiguration {
     /** The background loader waits this time of seconds after startup before loading events from the repository. (in secs) */
     public static final String PROPERTY_BACKGROUND_LOAD_DELAY = "load.delay";
 
+    /** The entire job handling waits time amount of seconds until it starts - to allow avoiding reassign on restart of a cluster */
+    public static final String PROPERTY_STARTUP_DELAY = "startup.delay";
+    
     /** Configuration switch for distributing the jobs. */
     public static final String PROPERTY_DISABLE_DISTRIBUTION = "job.consumermanager.disableDistribution";
 
@@ -142,6 +155,10 @@ public class JobManagerConfiguration {
 
     private volatile long backgroundLoadDelay;
 
+    private volatile long startupDelay;
+    
+    private volatile InitDelayingTopologyEventListener startupDelayListener;
+
     private volatile boolean disabledDistribution;
 
     private String storedCancelledJobsPath;
@@ -216,6 +233,20 @@ public class JobManagerConfiguration {
             resolver.close();
         }
         this.active.set(true);
+        
+        // SLING-5560 : use an InitDelayingTopologyEventListener
+        if (this.startupDelay > 0) {
+            logger.warn("activate: job manager will start in {} sec. ({})", this.startupDelay, PROPERTY_STARTUP_DELAY);
+            this.startupDelayListener = new InitDelayingTopologyEventListener(startupDelay, new TopologyEventListener() {
+
+                @Override
+                public void handleTopologyEvent(TopologyEvent event) {
+                    doHandleTopologyEvent(event);
+                }
+            }, this.scheduler, logger);
+        } else {
+            logger.warn("activate: job manager will start without delay. ({}:{})", PROPERTY_STARTUP_DELAY, this.startupDelay);
+        }
     }
 
     /**
@@ -225,6 +256,10 @@ public class JobManagerConfiguration {
     protected void update(final Map<String, Object> props) {
         this.disabledDistribution = PropertiesUtil.toBoolean(props.get(PROPERTY_DISABLE_DISTRIBUTION), DEFAULT_DISABLE_DISTRIBUTION);
         this.backgroundLoadDelay = PropertiesUtil.toLong(props.get(PROPERTY_BACKGROUND_LOAD_DELAY), DEFAULT_BACKGROUND_LOAD_DELAY);
+        // SLING-5560: note that currently you can't change the startupDelay to have
+        // an immediate effect - it will only have an effect on next activation.
+        // (as 'startup delay runnable' is already scheduled in activate)
+        this.startupDelay = PropertiesUtil.toLong(props.get(PROPERTY_STARTUP_DELAY), DEFAULT_STARTUP_DELAY);
         Utility.LOG_DEPRECATION_WARNINGS = PropertiesUtil.toBoolean(props.get(PROPERTY_LOG_DEPRECATION_WARNINGS), DEFAULT_LOG_DEPRECATION_WARNINGS);
     }
 
@@ -234,6 +269,10 @@ public class JobManagerConfiguration {
     @Deactivate
     protected void deactivate() {
         this.active.set(false);
+        if ( this.startupDelayListener != null) {
+            this.startupDelayListener.dispose();
+            this.startupDelayListener = null;
+        }
         this.stopProcessing();
     }
 
@@ -517,8 +556,18 @@ public class JobManagerConfiguration {
      * Therefore this method can't be invoked concurrently
      * @see org.apache.sling.discovery.TopologyEventListener#handleTopologyEvent(org.apache.sling.discovery.TopologyEvent)
      */
-    public void handleTopologyEvent(final TopologyEvent event) {
-        this.logger.debug("Received topology event {}", event);
+    public void handleTopologyEvent(TopologyEvent event) {
+        if ( this.startupDelayListener != null ) {
+            // with startup.delay > 0
+            this.startupDelayListener.handleTopologyEvent(event);
+        } else {
+            // classic (startup.delay <= 0)
+            this.logger.debug("Received topology event {}", event);
+            doHandleTopologyEvent(event);
+        }
+    }
+    
+    void doHandleTopologyEvent(final TopologyEvent event) {
 
         // check if there is a change of properties which doesn't affect us
         // but we need to use the new view !

Modified: sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/config/JobManagerConfigurationTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/config/JobManagerConfigurationTest.java?rev=1737012&r1=1737011&r2=1737012&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/config/JobManagerConfigurationTest.java (original)
+++ sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/config/JobManagerConfigurationTest.java Tue Mar 29 15:42:41 2016
@@ -40,7 +40,9 @@ import org.apache.sling.commons.schedule
 import org.apache.sling.discovery.ClusterView;
 import org.apache.sling.discovery.InstanceDescription;
 import org.apache.sling.discovery.TopologyEvent;
+import org.apache.sling.discovery.TopologyEventListener;
 import org.apache.sling.discovery.TopologyView;
+import org.apache.sling.discovery.commons.InitDelayingTopologyEventListener;
 import org.apache.sling.event.impl.TestUtil;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -207,6 +209,14 @@ public class JobManagerConfigurationTest
         final JobManagerConfiguration config = new JobManagerConfiguration();
         TestUtil.setFieldValue(config, "scheduler", scheduler);
         ((AtomicBoolean)TestUtil.getFieldValue(config, "active")).set(true);
+        InitDelayingTopologyEventListener startupDelayListener = new InitDelayingTopologyEventListener(1, new TopologyEventListener() {
+            
+            @Override
+            public void handleTopologyEvent(TopologyEvent event) {
+                config.doHandleTopologyEvent(event);
+            }
+        }, scheduler);;
+        TestUtil.setFieldValue(config, "startupDelayListener", startupDelayListener);
 
         config.addListener(ccl);
         ccl.await();

Modified: sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/it/AbstractJobHandlingTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/it/AbstractJobHandlingTest.java?rev=1737012&r1=1737011&r2=1737012&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/it/AbstractJobHandlingTest.java (original)
+++ sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/it/AbstractJobHandlingTest.java Tue Mar 29 15:42:41 2016
@@ -49,7 +49,9 @@ import org.apache.sling.event.jobs.consu
 import org.ops4j.pax.exam.Configuration;
 import org.ops4j.pax.exam.CoreOptions;
 import org.ops4j.pax.exam.Option;
+import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
@@ -57,6 +59,7 @@ import org.osgi.service.cm.Configuration
 import org.osgi.service.event.EventAdmin;
 import org.osgi.service.event.EventConstants;
 import org.osgi.service.event.EventHandler;
+import org.slf4j.LoggerFactory;
 
 public abstract class AbstractJobHandlingTest {
 
@@ -169,7 +172,14 @@ public abstract class AbstractJobHandlin
                 mavenBundle("org.apache.httpcomponents", "httpcore-osgi", "4.1.2"),
                 mavenBundle("org.apache.httpcomponents", "httpclient-osgi", "4.1.2"),
 
-                CoreOptions.bundle( bundleFile.toURI().toString() ),
+                mavenBundle("org.apache.sling", "org.apache.sling.discovery.commons", "1.0.12"),
+
+                // SLING-5560: delaying start of the sling.event bundle to
+                // ensure the parameter 'startup.delay' is properly set to 1sec
+                // for these ITs - as otherwise, the default of 30sec applies -
+                // which will cause the tests to fail
+                // @see setup() where the bundle is finally started - after reconfig
+                CoreOptions.bundle( bundleFile.toURI().toString() ).start(false),
 
                 junitBundles()
            );
@@ -202,13 +212,34 @@ public abstract class AbstractJobHandlin
             // ignore
         }
     }
-
+    
     public void setup() throws IOException {
         // set load delay to 3 sec
         final org.osgi.service.cm.Configuration c2 = this.configAdmin.getConfiguration("org.apache.sling.event.impl.jobs.jcr.PersistenceHandler", null);
         Dictionary<String, Object> p2 = new Hashtable<String, Object>();
         p2.put(JobManagerConfiguration.PROPERTY_BACKGROUND_LOAD_DELAY, 3L);
+        // and startup.delay to 1sec - otherwise default of 30sec breaks tests!
+        p2.put(JobManagerConfiguration.PROPERTY_STARTUP_DELAY, 1L);
         c2.update(p2);
+        
+        // SLING-5560 : since the above (re)config is now applied, we're safe
+        // to go ahead and start the sling.event bundle.
+        // this time, the JobManagerConfiguration will be activated
+        // with the 'startup.delay' set to 1sec - so that ITs actually succeed
+        try {
+            Bundle[] bundles = bc.getBundles();
+            for (Bundle bundle : bundles) {
+                if (bundle.getSymbolicName().contains("sling.event")) {
+                    // assuming we only have 1 bundle that contains 'sling.event'
+                    LoggerFactory.getLogger(getClass()).info("starting bundle... "+bundle);
+                    bundle.start();
+                    break;
+                }
+            }
+        } catch (BundleException e) {
+            LoggerFactory.getLogger(getClass()).error("could not start sling.event bundle: "+e, e);
+            throw new RuntimeException(e);
+        }
     }
 
     private int deleteCount;