You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2013/07/26 12:07:08 UTC

svn commit: r1507250 - in /sling/trunk/bundles/commons/scheduler: ./ src/main/java/org/apache/sling/commons/scheduler/impl/

Author: cziegeler
Date: Fri Jul 26 10:07:07 2013
New Revision: 1507250

URL: http://svn.apache.org/r1507250
Log:
SLING-2979 : Add support for running scheduled task only on the leader

Added:
    sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/TopologyHandler.java   (with props)
Modified:
    sling/trunk/bundles/commons/scheduler/pom.xml
    sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzJobExecutor.java
    sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java

Modified: sling/trunk/bundles/commons/scheduler/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/scheduler/pom.xml?rev=1507250&r1=1507249&r2=1507250&view=diff
==============================================================================
--- sling/trunk/bundles/commons/scheduler/pom.xml (original)
+++ sling/trunk/bundles/commons/scheduler/pom.xml Fri Jul 26 10:07:07 2013
@@ -58,6 +58,7 @@
                             org.apache.sling.commons.scheduler.impl
                         </Private-Package>
                         <DynamicImport-Package>
+                            org.apache.sling.discovery,
                             commonj.work,
                             com.mchange.v2.c3p0,
                             javax.ejb,

Modified: sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzJobExecutor.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzJobExecutor.java?rev=1507250&r1=1507249&r2=1507250&view=diff
==============================================================================
--- sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzJobExecutor.java (original)
+++ sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzJobExecutor.java Fri Jul 26 10:07:07 2013
@@ -18,6 +18,7 @@ package org.apache.sling.commons.schedul
 
 import java.io.Serializable;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.sling.commons.scheduler.JobContext;
 import org.quartz.Job;
@@ -27,12 +28,15 @@ import org.quartz.JobExecutionException;
 import org.slf4j.Logger;
 
 /**
- * This component is resposible to launch a {@link org.apache.sling.commons.scheduler.Job}
+ * This component is responsible to launch a {@link org.apache.sling.commons.scheduler.Job}
  * or {@link Runnable} in a Quartz Scheduler.
  *
  */
 public class QuartzJobExecutor implements Job {
 
+    /** Is this instance the leader? */
+    public static final AtomicBoolean IS_LEADER = new AtomicBoolean(true);
+
     /**
      * @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
      */
@@ -40,6 +44,12 @@ public class QuartzJobExecutor implement
 
         final JobDataMap data = context.getJobDetail().getJobDataMap();
 
+        // check leader
+        final boolean onLeaderOnly = data.getBooleanValue(QuartzScheduler.DATA_MAP_ON_LEADER_ONLY);
+        if (onLeaderOnly && !IS_LEADER.get()) {
+            return;
+        }
+
         final Object job = data.get(QuartzScheduler.DATA_MAP_OBJECT);
         final Logger logger = (Logger)data.get(QuartzScheduler.DATA_MAP_LOGGER);
 

Modified: sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java?rev=1507250&r1=1507249&r2=1507250&view=diff
==============================================================================
--- sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java (original)
+++ sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java Fri Jul 26 10:07:07 2013
@@ -87,6 +87,9 @@ public class QuartzScheduler implements 
     /** Map key for the logger. */
     static final String DATA_MAP_LOGGER = "QuartzJobScheduler.Logger";
 
+    /** Map key for the isLeader information (Boolean). */
+    static final String DATA_MAP_ON_LEADER_ONLY = "QuartzJobScheduler.OnLeaderOnly";
+
     /** The quartz scheduler. */
     private volatile org.quartz.Scheduler scheduler;
 
@@ -223,6 +226,7 @@ public class QuartzScheduler implements 
         this.threadPool = null;
     }
 
+
     /**
      * Initialize the data map for the job executor.
      * @param jobName
@@ -232,17 +236,18 @@ public class QuartzScheduler implements 
      * @return
      */
     private JobDataMap initDataMap(final String  jobName,
-                                     final Object  job,
-                                     final Map<String, Serializable> config) {
+                                   final Object  job,
+                                   final InternalScheduleOptions options) {
         final JobDataMap jobDataMap = new JobDataMap();
 
         jobDataMap.put(DATA_MAP_OBJECT, job);
 
         jobDataMap.put(DATA_MAP_NAME, jobName);
         jobDataMap.put(DATA_MAP_LOGGER, this.logger);
-        if ( config != null ) {
-            jobDataMap.put(DATA_MAP_CONFIGURATION, config);
+        if ( options.configuration != null ) {
+            jobDataMap.put(DATA_MAP_CONFIGURATION, options.configuration);
         }
+        jobDataMap.put(DATA_MAP_ON_LEADER_ONLY, options.onLeaderOnly);
 
         return jobDataMap;
     }
@@ -421,9 +426,13 @@ public class QuartzScheduler implements 
                 try {
                     final String name = getServiceIdentifier(ref);
                     final Boolean concurrent = (Boolean)ref.getProperty(Scheduler.PROPERTY_SCHEDULER_CONCURRENT);
+                    final Boolean onLeaderOnly = (Boolean)ref.getProperty(Scheduler.PROPERTY_SCHEDULER_LEADER_ONLY);
                     final String expression = (String)ref.getProperty(Scheduler.PROPERTY_SCHEDULER_EXPRESSION);
                     if ( expression != null ) {
-                        this.scheduleJob(job, this.EXPR(expression).name(name).canRunConcurrently((concurrent != null ? concurrent : true)));
+                        this.scheduleJob(job, this.EXPR(expression)
+                                .name(name)
+                                .canRunConcurrently((concurrent != null ? concurrent : true))
+                                .onLeaderOnly(onLeaderOnly != null ? onLeaderOnly : false));
                     } else {
                         final Long period = (Long)ref.getProperty(Scheduler.PROPERTY_SCHEDULER_PERIOD);
                         if ( period != null ) {
@@ -434,7 +443,10 @@ public class QuartzScheduler implements 
                                 if ( ref.getProperty(Scheduler.PROPERTY_SCHEDULER_IMMEDIATE) != null ) {
                                     immediate = (Boolean)ref.getProperty(Scheduler.PROPERTY_SCHEDULER_IMMEDIATE);
                                 }
-                                this.scheduleJob(job, this.PERIODIC(period, immediate).name(name).canRunConcurrently((concurrent != null ? concurrent : true)));
+                                this.scheduleJob(job, this.PERIODIC(period, immediate)
+                                        .name(name)
+                                        .canRunConcurrently((concurrent != null ? concurrent : true))
+                                        .onLeaderOnly(onLeaderOnly != null ? onLeaderOnly : false));
                             }
                         } else {
                             this.logger.debug("Ignoring servce {} : no scheduling property found.", ref);
@@ -783,7 +795,7 @@ public class QuartzScheduler implements 
         final Trigger trigger = opts.trigger.withIdentity(name).build();
 
         // create the data map
-        final JobDataMap jobDataMap = this.initDataMap(name, job, opts.configuration);
+        final JobDataMap jobDataMap = this.initDataMap(name, job, opts);
 
         final JobDetail detail = this.createJobDetail(name, jobDataMap, opts.canRunConcurrently);
 

Added: sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/TopologyHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/TopologyHandler.java?rev=1507250&view=auto
==============================================================================
--- sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/TopologyHandler.java (added)
+++ sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/TopologyHandler.java Fri Jul 26 10:07:07 2013
@@ -0,0 +1,39 @@
+/*
+ * 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.commons.scheduler.impl;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.discovery.TopologyEvent;
+import org.apache.sling.discovery.TopologyEvent.Type;
+import org.apache.sling.discovery.TopologyEventListener;
+
+@Component
+@Service(value=TopologyEventListener.class)
+public class TopologyHandler implements TopologyEventListener {
+
+    /**
+     * @see org.apache.sling.discovery.TopologyEventListener#handleTopologyEvent(org.apache.sling.discovery.TopologyEvent)
+     */
+    public void handleTopologyEvent(final TopologyEvent event) {
+        if ( event.getType() == Type.TOPOLOGY_INIT || event.getType() == Type.TOPOLOGY_CHANGED ) {
+            QuartzJobExecutor.IS_LEADER.set(event.getNewView().getLocalInstance().isLeader());
+        } else if ( event.getType() == Type.TOPOLOGY_CHANGING ) {
+            QuartzJobExecutor.IS_LEADER.set(false);
+        }
+    }
+}

Propchange: sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/TopologyHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/TopologyHandler.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url



Re: svn commit: r1507250 - in /sling/trunk/bundles/commons/scheduler: ./ src/main/java/org/apache/sling/commons/scheduler/impl/

Posted by Felix Meschberger <fm...@adobe.com>.
Hi

Am 29.07.2013 um 16:22 schrieb Carsten Ziegeler:

> Good catch, somehow I was under the impression that bnd calculates this for
> us...but of course it doesn't as it (correctly) takes the statement written
> to the pom.

BND will calculate the range for Import-Package but it probably cannot for DynamicImport-Package: For example there is no safe way to derive a version range for a dynamic import of the form some.package.*. But for a fixed name (such as o.a.s.discovery) this might probably be feasible.

> 
> Fixed now

Thanks.

Regards
Felix

> 
> Carsten
> 
> 2013/7/29 Felix Meschberger <fm...@adobe.com>
> 
>> Hi
>> 
>> Am 26.07.2013 um 12:07 schrieb <cz...@apache.org> <
>> cziegeler@apache.org>:
>> 
>>>                        <DynamicImport-Package>
>>> +                            org.apache.sling.discovery,
>> 
>> Can we at least declare a very broad import version range ? such as
>> [1.0,2) ?
>> 
>> Regards
>> Felix
>> 
>> 
> 
> 
> -- 
> Carsten Ziegeler
> cziegeler@apache.org


Re: svn commit: r1507250 - in /sling/trunk/bundles/commons/scheduler: ./ src/main/java/org/apache/sling/commons/scheduler/impl/

Posted by Carsten Ziegeler <cz...@apache.org>.
Good catch, somehow I was under the impression that bnd calculates this for
us...but of course it doesn't as it (correctly) takes the statement written
to the pom.

Fixed now

Carsten

2013/7/29 Felix Meschberger <fm...@adobe.com>

> Hi
>
> Am 26.07.2013 um 12:07 schrieb <cz...@apache.org> <
> cziegeler@apache.org>:
>
> >                         <DynamicImport-Package>
> > +                            org.apache.sling.discovery,
>
> Can we at least declare a very broad import version range ? such as
> [1.0,2) ?
>
> Regards
> Felix
>
>


-- 
Carsten Ziegeler
cziegeler@apache.org

Re: svn commit: r1507250 - in /sling/trunk/bundles/commons/scheduler: ./ src/main/java/org/apache/sling/commons/scheduler/impl/

Posted by Felix Meschberger <fm...@adobe.com>.
Hi

Am 26.07.2013 um 12:07 schrieb <cz...@apache.org> <cz...@apache.org>:

>                         <DynamicImport-Package>
> +                            org.apache.sling.discovery,

Can we at least declare a very broad import version range ? such as [1.0,2) ?

Regards
Felix