incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cziege...@apache.org
Subject svn commit: r792809 - /sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java
Date Fri, 10 Jul 2009 05:53:13 GMT
Author: cziegeler
Date: Fri Jul 10 05:53:13 2009
New Revision: 792809

URL: http://svn.apache.org/viewvc?rev=792809&view=rev
Log:
SLING-1040 : This agressive synching has been introduced by SLING-984 and is completly wrong.
I've cleaned this up and the syncing is now reduced to a minimum.

Modified:
    sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java

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=792809&r1=792808&r2=792809&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 10 05:53:13 2009
@@ -63,6 +63,8 @@
 
     protected static final String THREAD_POOL_NAME = "SLING_SCHEDULER";
 
+    protected static final String PREFIX = "Apache Sling Quartz Scheduler ";
+
     protected static final String QUARTZ_SCHEDULER_NAME = "ApacheSling";
 
     /** Map key for the job object */
@@ -80,10 +82,13 @@
     /** Map key for the concurrent handler */
     static final String DATA_MAP_CONCURRENT_HANDLER = "QuartzJobExecutor.ConcurrentHandler";
 
+    /** Theq quartz scheduler. */
     protected org.quartz.Scheduler scheduler;
 
-    protected final List<Object[]> registeredJobs = new ArrayList<Object[]>();
+    /** List of registrations while this service is not activated yet. */
+    protected final List<Registration> registeredJobs = new ArrayList<Registration>();
 
+    /** The component context. */
     protected ComponentContext context;
 
     /** @scr.reference */
@@ -95,21 +100,25 @@
      * @param ctx The component context.
      * @throws Exception
      */
-    protected void activate(ComponentContext ctx) throws Exception {
+    protected void activate(final ComponentContext ctx) throws Exception {
         this.context = ctx;
+        // start scheduler
+        this.scheduler = this.init();
+
+        final Registration[] regs;
         synchronized ( this.registeredJobs ) {
-            this.init();
-            for( Object[] arr : this.registeredJobs ) {
-                try {
-                    this.register((String)arr[0], (ServiceReference)arr[1]);
-                } catch (Exception e) {
-                    // we don't want that one malicious service brings down the scheduler,
so we just log
-                    // the exception and continue
-                    this.logger.error("Exception during registering job service " + arr[1],
e);
-                }
-            }
+            regs = this.registeredJobs.toArray(new Registration[this.registeredJobs.size()]);
             this.registeredJobs.clear();
         }
+        for( final Registration reg : regs ) {
+            try {
+                this.register(reg.componentName, reg.reference);
+            } catch (Exception e) {
+                // we don't want that one malicious service brings down the scheduler, so
we just log
+                // the exception and continue
+                this.logger.error("Exception during registering " + reg.componentName + "
service " + reg.reference, e);
+            }
+        }
     }
 
     /**
@@ -117,19 +126,25 @@
      * Stop the scheduler.
      * @param ctx The component context.
      */
-    protected void deactivate(ComponentContext ctx) {
-        synchronized (this.registeredJobs ) {
-            this.dispose();
-        }
+    protected void deactivate(final ComponentContext ctx) {
+        final org.quartz.Scheduler s = this.scheduler;
+        this.scheduler = null;
+        this.dispose(s);
         this.context = null;
     }
 
-    protected void init() throws SchedulerException {
+    /**
+     * Initialize the quartz scheduler
+     * @return Return the new scheduler instance.
+     * @throws SchedulerException
+     */
+    protected org.quartz.Scheduler init() throws SchedulerException {
         // if we don't have a thread pool manager, we use the default thread pool
         final ThreadPoolManager tpm = this.threadPoolManager;
+        org.quartz.Scheduler s;
         if ( tpm == null ) {
             final SchedulerFactory factory = new StdSchedulerFactory();
-            this.scheduler = factory.getScheduler();
+            s = factory.getScheduler();
         } else {
             // create the pool
             final ThreadPool pool = tpm.get(THREAD_POOL_NAME);
@@ -142,35 +157,39 @@
             // quartz does not provide a way to get the scheduler by name AND runID, so we
have to iterate!
             @SuppressWarnings("unchecked")
             final Iterator<org.quartz.Scheduler> allSchedulersIter = factory.getAllSchedulers().iterator();
-            this.scheduler = null;
-            while ( this.scheduler == null && allSchedulersIter.hasNext() ) {
+            s = null;
+            while ( s == null && allSchedulersIter.hasNext() ) {
                 final org.quartz.Scheduler current = allSchedulersIter.next();
                 if ( QUARTZ_SCHEDULER_NAME.equals(current.getSchedulerName())
                      && runID.equals(current.getSchedulerInstanceId()) ) {
-                    this.scheduler = current;
+                    s = current;
                 }
             }
-            if ( this.scheduler == null ) {
+            if ( s == null ) {
                 throw new SchedulerException("Unable to find new scheduler with name " +
QUARTZ_SCHEDULER_NAME + " and run ID " + runID);
             }
         }
-        this.scheduler.start();
+        s.start();
         if ( this.logger.isDebugEnabled() ) {
-            this.logger.debug("Scheduler started.");
+            this.logger.debug(PREFIX + "started.");
         }
+        return s;
     }
 
-    protected void dispose() {
-        if ( this.scheduler != null ) {
+    /**
+     * Dispose the quartz scheduler
+     * @param s The scheduler.
+     */
+    protected void dispose(final org.quartz.Scheduler s) {
+        if ( s != null ) {
             try {
-                this.scheduler.shutdown();
+                s.shutdown();
             } catch (SchedulerException e) {
                 this.logger.debug("Exception during shutdown of scheduler.", e);
             }
             if ( this.logger.isDebugEnabled() ) {
-                this.logger.debug("Scheduler stopped.");
+                this.logger.debug(PREFIX + "stopped.");
             }
-            this.scheduler = null;
         }
     }
 
@@ -203,7 +222,7 @@
             } catch (final SchedulerException ignored) {
             }
         } else {
-            name = "Sling Quartz Scheduler " + UUID.randomUUID().toString();
+            name = PREFIX + UUID.randomUUID().toString();
         }
 
         // create the data map
@@ -291,7 +310,7 @@
     throws Exception {
         final long ms = period * 1000;
         if ( name == null ) {
-            name = "Sling Quartz Scheduler " + UUID.randomUUID().toString();
+            name = PREFIX + UUID.randomUUID().toString();
         }
         final SimpleTrigger timeEntry =
             new SimpleTrigger(name, DEFAULT_QUARTZ_JOB_GROUP, new Date(System.currentTimeMillis()
+ ms), null,
@@ -320,7 +339,7 @@
      */
     public void fireJobAt(String name, Object job, Map<String, Serializable> config,
Date date) throws Exception {
         if ( name == null ) {
-            name = "Sling Quartz Scheduler " + UUID.randomUUID().toString();
+            name = PREFIX + UUID.randomUUID().toString();
         }
         final SimpleTrigger trigger = new SimpleTrigger(name, DEFAULT_QUARTZ_JOB_GROUP, date);
         this.scheduleJob(name, job, config, trigger, true);
@@ -357,6 +376,12 @@
         return name;
     }
 
+    /**
+     * Register a job or task
+     * @param type The type (job or task)
+     * @param ref The service reference
+     * @throws Exception If the registration can't be performed
+     */
     private void register(String type, ServiceReference ref)
     throws Exception {
         final Object job = this.context.locateService(type, ref);
@@ -376,6 +401,10 @@
         }
     }
 
+    /**
+     * Unregister a service.
+     * @param ref The service reference.
+     */
     private void unregister(ServiceReference ref) {
         final String name = getServiceIdentifier(ref);
         this.removeJob(name);
@@ -388,11 +417,11 @@
      */
     protected void bindJob(ServiceReference ref)
     throws Exception {
-        synchronized ( this.registeredJobs ) {
-            if ( this.scheduler != null ) {
-                this.register("job", ref);
-            } else {
-                this.registeredJobs.add(new Object[] {"job", ref});
+        if ( this.scheduler != null ) {
+            this.register(Registration.JOB, ref);
+        } else {
+            synchronized ( this.registeredJobs ) {
+                this.registeredJobs.add(new Registration(ref, Registration.JOB));
             }
         }
     }
@@ -402,45 +431,79 @@
      * @param ref
      */
     protected void unbindJob(ServiceReference ref) {
-        synchronized ( this.registeredJobs ) {
-            if ( this.scheduler != null ) {
-                this.unregister(ref);
+        if ( this.scheduler != null ) {
+            this.unregister(ref);
+        } else {
+            synchronized ( this.registeredJobs ) {
+                this.registeredJobs.remove(new Registration(ref, Registration.JOB));
             }
         }
     }
 
     /**
-     * Bind a new job.
+     * Bind a new task.
      * @param ref
      * @throws Exception
      */
     protected void bindTask(ServiceReference ref)
     throws Exception {
-        synchronized ( this.registeredJobs ) {
-            if ( this.scheduler != null ) {
-                this.register("task", ref);
-            } else {
-                this.registeredJobs.add(new Object[] {"task", ref});
+        if ( this.scheduler != null ) {
+            this.register(Registration.TASK, ref);
+        } else {
+            synchronized ( this.registeredJobs ) {
+                this.registeredJobs.add(new Registration(ref, Registration.TASK));
             }
         }
     }
 
     /**
-     * Unbind a job.
+     * Unbind a task.
      * @param ref
      */
     protected void unbindTask(ServiceReference ref) {
-        synchronized ( this.registeredJobs ) {
-            if ( this.scheduler != null ) {
-                this.unregister(ref);
+        if ( this.scheduler != null ) {
+            this.unregister(ref);
+        } else {
+            synchronized ( this.registeredJobs ) {
+                this.registeredJobs.remove(new Registration(ref, Registration.TASK));
             }
         }
     }
 
-    private static final class QuartzThreadPool implements org.quartz.spi.ThreadPool {
+    /**
+     * Helper class holding a registration if this service is not active yet.
+     */
+    private static final class Registration {
+        public static final String JOB = "job";
+        public static final String TASK = "task";
 
-        /** Default log. */
-        protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+        public final ServiceReference reference;
+        public final String componentName;
+
+        public Registration(final ServiceReference r, final String name) {
+            this.reference = r;
+            this.componentName = name;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if ( !(obj instanceof Registration) ) {
+                return false;
+            }
+            if ( obj == this ) {
+                return true;
+            }
+            return this.reference.equals(((Registration)obj).reference);
+        }
+
+        @Override
+        public int hashCode() {
+            return this.reference.hashCode();
+        }
+    }
+
+
+    private static final class QuartzThreadPool implements org.quartz.spi.ThreadPool {
 
         /** Our executor thread pool */
         private ThreadPool executor;



Mime
View raw message