[jboss-cvs] jboss-seam/src/main/org/jboss/seam/core ...

Gavin King gavin.king at jboss.com
Thu May 31 17:05:29 EDT 2007


  User: gavin   
  Date: 07/05/31 17:05:28

  Modified:    src/main/org/jboss/seam/core         AbstractDispatcher.java
                        Dispatcher.java Events.java
                        LocalTimerServiceDispatcher.java
                        ThreadPoolDispatcher.java
                        TimerServiceDispatcher.java
  Added:       src/main/org/jboss/seam/core         TimerSchedule.java
  Removed:     src/main/org/jboss/seam/core        
                        TimerServiceSchedule.java
  Log:
  timed events for ThreadPoolExecutor
  
  Revision  Changes    Path
  1.3       +41 -0     jboss-seam/src/main/org/jboss/seam/core/AbstractDispatcher.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: AbstractDispatcher.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/core/AbstractDispatcher.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -b -r1.2 -r1.3
  --- AbstractDispatcher.java	31 May 2007 01:17:15 -0000	1.2
  +++ AbstractDispatcher.java	31 May 2007 21:05:28 -0000	1.3
  @@ -1,11 +1,17 @@
   package org.jboss.seam.core;
   
   import java.io.Serializable;
  +import java.lang.annotation.Annotation;
   import java.lang.reflect.Method;
  +import java.util.Date;
   
   import org.jboss.seam.Component;
  +import org.jboss.seam.annotations.timer.Duration;
  +import org.jboss.seam.annotations.timer.Expiration;
  +import org.jboss.seam.annotations.timer.IntervalDuration;
   import org.jboss.seam.contexts.Contexts;
   import org.jboss.seam.contexts.Lifecycle;
  +import org.jboss.seam.intercept.InvocationContext;
   import org.jboss.seam.util.Reflections;
   
   /**
  @@ -96,6 +102,11 @@
            this.componentName = componentName;
         }
         
  +      public AsynchronousInvocation(InvocationContext invocation, Component component)
  +      {
  +         this( invocation.getMethod(), component.getName(), invocation.getParameters() );
  +      }
  +      
         @Override
         protected void call()
         {
  @@ -136,4 +147,34 @@
         
      }
      
  +   protected TimerSchedule createSchedule(InvocationContext invocation)
  +   {
  +      Long duration = null;
  +      Date expiration = null;
  +      Long intervalDuration = null;
  +      Annotation[][] parameterAnnotations = invocation.getMethod().getParameterAnnotations();
  +      for ( int i=0; i<parameterAnnotations.length; i++ )
  +      {
  +         Annotation[] annotations = parameterAnnotations[i];
  +         for (Annotation annotation: annotations)
  +         {
  +            if ( annotation.annotationType().equals(Duration.class) )
  +            {
  +               duration = (Long) invocation.getParameters()[i];
  +            }
  +            else if ( annotation.annotationType().equals(IntervalDuration.class) )
  +            {
  +               intervalDuration = (Long) invocation.getParameters()[i];
  +            }
  +            else if ( annotation.annotationType().equals(Expiration.class) )
  +            {
  +               expiration = (Date) invocation.getParameters()[i];
  +            }
  +         }
  +      }
  +      
  +      TimerSchedule schedule = new TimerSchedule(duration, expiration, intervalDuration);
  +      return schedule;
  +   }
  +   
   }
  
  
  
  1.21      +4 -3      jboss-seam/src/main/org/jboss/seam/core/Dispatcher.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: Dispatcher.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/core/Dispatcher.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -b -r1.20 -r1.21
  --- Dispatcher.java	31 May 2007 01:17:15 -0000	1.20
  +++ Dispatcher.java	31 May 2007 21:05:28 -0000	1.21
  @@ -14,20 +14,21 @@
   public interface Dispatcher<T, S>
   {
      /**
  -    * Schedule an asynchronous method call
  +    * Schedule an asynchronous method call, examining annotations
  +    * upon the method to determine the schedule
       * 
       * @return some kind of timer object, or null
       */
      public T scheduleInvocation(InvocationContext invocation, Component component);
      /**
  -    * Schedule a timed event
  +    * Schedule a timed (delayed and/or periodic) event
       * 
       * @return some kind of timer object, or null
       */
      public T scheduleTimedEvent(String type, S schedule, Object... parameters);
      
      /**
  -    * Schedule an asynchronous event
  +    * Schedule an immediate asynchronous event
       * 
       * @return some kind of timer object, or null
       */
  
  
  
  1.27      +1 -1      jboss-seam/src/main/org/jboss/seam/core/Events.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: Events.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/core/Events.java,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -b -r1.26 -r1.27
  --- Events.java	31 May 2007 00:55:40 -0000	1.26
  +++ Events.java	31 May 2007 21:05:28 -0000	1.27
  @@ -98,7 +98,7 @@
      /**
       * Raise an event that is to be processed according to a "schedule"
       * 
  -    * @see TimerServiceSchedule for use of the EJB timer service
  +    * @see TimerSchedule for use of the EJB timer service
       * 
       * @param type the event type
       * @param schedule the schedule object, specific to the dispatcher strategy
  
  
  
  1.2       +1 -1      jboss-seam/src/main/org/jboss/seam/core/LocalTimerServiceDispatcher.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: LocalTimerServiceDispatcher.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/core/LocalTimerServiceDispatcher.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -b -r1.1 -r1.2
  --- LocalTimerServiceDispatcher.java	31 May 2007 01:17:15 -0000	1.1
  +++ LocalTimerServiceDispatcher.java	31 May 2007 21:05:28 -0000	1.2
  @@ -12,7 +12,7 @@
    *
    */
   @Local
  -public interface LocalTimerServiceDispatcher extends Dispatcher<Timer, TimerServiceSchedule>
  +public interface LocalTimerServiceDispatcher extends Dispatcher<Timer, TimerSchedule>
   {   
      public Object call(Callable task);
   }
  
  
  
  1.3       +92 -25    jboss-seam/src/main/org/jboss/seam/core/ThreadPoolDispatcher.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: ThreadPoolDispatcher.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/core/ThreadPoolDispatcher.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -b -r1.2 -r1.3
  --- ThreadPoolDispatcher.java	31 May 2007 01:17:15 -0000	1.2
  +++ ThreadPoolDispatcher.java	31 May 2007 21:05:28 -0000	1.3
  @@ -2,14 +2,17 @@
   
   import static org.jboss.seam.annotations.Install.BUILT_IN;
   
  -import java.util.concurrent.ExecutorService;
  +import java.util.Date;
   import java.util.concurrent.Executors;
   import java.util.concurrent.Future;
  +import java.util.concurrent.ScheduledExecutorService;
  +import java.util.concurrent.TimeUnit;
   
   import javax.interceptor.Interceptors;
   
   import org.jboss.seam.Component;
   import org.jboss.seam.ScopeType;
  +import org.jboss.seam.annotations.Destroy;
   import org.jboss.seam.annotations.Install;
   import org.jboss.seam.annotations.Name;
   import org.jboss.seam.annotations.Scope;
  @@ -18,7 +21,7 @@
   
   /**
    * Dispatcher implementation that uses a java.util.concurrent
  - * ThreadPoolExecutor.
  + * ScheduledThreadPoolExecutor.
    * 
    * @author Gavin King
    *
  @@ -26,40 +29,104 @@
   @Scope(ScopeType.APPLICATION)
   @Name("org.jboss.seam.core.dispatcher")
   @Interceptors(SeamInterceptor.class)
  - at Install(value=false, precedence=BUILT_IN)
  -public class ThreadPoolDispatcher extends AbstractDispatcher<Future, Object>
  + at Install(precedence=BUILT_IN)
  +public class ThreadPoolDispatcher extends AbstractDispatcher<Future, TimerSchedule>
   {
  -   private ExecutorService executor = Executors.newCachedThreadPool();
  +   private int threadPoolSize = 10; 
       
  -   public Future scheduleTimedEvent(String type, Object schedule, Object... parameters)
  -   {
  -      throw new UnsupportedOperationException();
  -   }
  +   private ScheduledExecutorService executor = Executors.newScheduledThreadPool(threadPoolSize);
      
      public Future scheduleAsynchronousEvent(String type, Object... parameters)
      {  
  -      final Asynchronous event = new AsynchronousEvent(type, parameters);
  -      return executor.submit( new Runnable() {
  -         public void run()
  -         {
  -            event.execute(null);
  +      return executor.submit( new RunnableAsynchronous( new AsynchronousEvent(type, parameters) ) );
            }
  -      } );
  +    
  +   public Future scheduleTimedEvent(String type, TimerSchedule schedule, Object... parameters)
  +   {
  +      return scheduleWithExecutorService( schedule, new RunnableAsynchronous( new AsynchronousEvent(type, parameters) ) );
      }
       
      public Future scheduleInvocation(InvocationContext invocation, Component component)
      {
  -      final Asynchronous call = new AsynchronousInvocation( 
  -               invocation.getMethod(),
  -               component.getName(),
  -               invocation.getParameters() 
  +      return scheduleWithExecutorService( 
  +               createSchedule(invocation), 
  +               new RunnableAsynchronous( new AsynchronousInvocation(invocation, component) ) 
               );
  -      return executor.submit( new Runnable() {
  +   }
  +   
  +   private static long toDuration(Date expiration)
  +   {
  +      return expiration.getTime() - new Date().getTime();
  +   }
  +   
  +   private Future scheduleWithExecutorService(TimerSchedule schedule, Runnable runnable)
  +   {
  +      if ( schedule.getIntervalDuration()!=null )
  +      {
  +         if ( schedule.getExpiration()!=null )
  +         {
  +            return executor.scheduleAtFixedRate( runnable, toDuration( schedule.getExpiration() ), schedule.getIntervalDuration(), TimeUnit.MILLISECONDS );
  +         }
  +         else if ( schedule.getDuration()!=null )
  +         {
  +             return executor.scheduleAtFixedRate( runnable, schedule.getDuration(), schedule.getIntervalDuration(), TimeUnit.MILLISECONDS );
  +         }
  +         else
  +         {
  +            return executor.scheduleAtFixedRate( runnable, 0l, schedule.getIntervalDuration(), TimeUnit.MILLISECONDS );
  +         }
  +      }
  +      else if ( schedule.getExpiration()!=null )
  +      {
  +          return executor.schedule( runnable, toDuration( schedule.getExpiration() ), TimeUnit.MILLISECONDS );
  +      }
  +      else if ( schedule.getDuration()!=null )
  +      {
  +          return executor.schedule( runnable, schedule.getDuration(), TimeUnit.MILLISECONDS );
  +      }
  +      else
  +      {
  +         return executor.schedule(runnable, 0l, TimeUnit.MILLISECONDS);
  +      }
  +   }
  +   
  +   @Destroy
  +   public void destroy()
  +   {
  +      executor.shutdown();
  +      try
  +      {
  +         executor.awaitTermination(5, TimeUnit.SECONDS);
  +      }
  +      catch (InterruptedException ie)
  +      {
  +         
  +      }
  +   }
  +   
  +   static class RunnableAsynchronous implements Runnable
  +   {
  +      private AbstractDispatcher.Asynchronous async;
  +      
  +      RunnableAsynchronous(Asynchronous async)
  +      {
  +         this.async = async;
  +      }
  +      
            public void run()
            {
  -            call.execute(null);
  +         async.execute(null);
  +      }
            }
  -      } );
  +
  +   public int getThreadPoolSize()
  +   {
  +      return threadPoolSize;
  +   }
  +
  +   public void setThreadPoolSize(int threadPoolSize)
  +   {
  +      this.threadPoolSize = threadPoolSize;
      }
      
   }
  
  
  
  1.3       +20 -60    jboss-seam/src/main/org/jboss/seam/core/TimerServiceDispatcher.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: TimerServiceDispatcher.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/core/TimerServiceDispatcher.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -b -r1.2 -r1.3
  --- TimerServiceDispatcher.java	31 May 2007 01:17:15 -0000	1.2
  +++ TimerServiceDispatcher.java	31 May 2007 21:05:28 -0000	1.3
  @@ -3,7 +3,6 @@
   import static org.jboss.seam.annotations.Install.BUILT_IN;
   
   import java.io.Serializable;
  -import java.lang.annotation.Annotation;
   import java.util.Date;
   import java.util.concurrent.Callable;
   
  @@ -21,9 +20,6 @@
   import org.jboss.seam.Component;
   import org.jboss.seam.annotations.Install;
   import org.jboss.seam.annotations.Name;
  -import org.jboss.seam.annotations.timer.Duration;
  -import org.jboss.seam.annotations.timer.Expiration;
  -import org.jboss.seam.annotations.timer.IntervalDuration;
   import org.jboss.seam.ejb.SeamInterceptor;
   import org.jboss.seam.intercept.InvocationContext;
   
  @@ -39,7 +35,7 @@
   @Interceptors(SeamInterceptor.class)
   @Install(value=false, precedence=BUILT_IN)
   public class TimerServiceDispatcher 
  -   extends AbstractDispatcher<Timer, TimerServiceSchedule>
  +   extends AbstractDispatcher<Timer, TimerSchedule>
      implements LocalTimerServiceDispatcher
   {
      
  @@ -54,86 +50,50 @@
         ( (Asynchronous) timer.getInfo() ).execute(timer);
      }
      
  -   public Timer scheduleTimedEvent(String type, TimerServiceSchedule timerServiceSchedule, Object... parameters)
  +   public Timer scheduleTimedEvent(String type, TimerSchedule schedule, Object... parameters)
      {
  -      return schedule( 
  -               timerServiceSchedule.getDuration(), 
  -               timerServiceSchedule.getExpiration(), 
  -               timerServiceSchedule.getIntervalDuration(), 
  -               new AsynchronousEvent(type, parameters) 
  -            );
  +      return new TimerProxy( scheduleWithTimerService( schedule, new AsynchronousEvent(type, parameters) ) );
      }
      
      public Timer scheduleAsynchronousEvent(String type, Object... parameters)
      {
  -      return schedule( 0l, null, null, new AsynchronousEvent(type, parameters) );
  +      return new TimerProxy( timerService.createTimer( 0l, new AsynchronousEvent(type, parameters) ) );
      }
      
      public Timer scheduleInvocation(InvocationContext invocation, Component component)
      {
  -      Long duration = 0l;
  -      Date expiration = null;
  -      Long intervalDuration = null;
  -      Annotation[][] parameterAnnotations = invocation.getMethod().getParameterAnnotations();
  -      for ( int i=0; i<parameterAnnotations.length; i++ )
  -      {
  -         Annotation[] annotations = parameterAnnotations[i];
  -         for (Annotation annotation: annotations)
  -         {
  -            if ( annotation.annotationType().equals(Duration.class) )
  -            {
  -               duration = (Long) invocation.getParameters()[i];
  -            }
  -            else if ( annotation.annotationType().equals(IntervalDuration.class) )
  -            {
  -               intervalDuration = (Long) invocation.getParameters()[i];
  -            }
  -            else if ( annotation.annotationType().equals(Expiration.class) )
  -            {
  -               expiration = (Date) invocation.getParameters()[i];
  -            }
  -         }
  -      }
  -
  -      AsynchronousInvocation asynchronousInvocation = new AsynchronousInvocation(
  -            invocation.getMethod(), 
  -            component.getName(), 
  -            invocation.getParameters()
  -         );
  -      
  -      return schedule(duration, expiration, intervalDuration, asynchronousInvocation);
  +      return new TimerProxy( scheduleWithTimerService( createSchedule(invocation), new AsynchronousInvocation(invocation, component) ) );
         
      }
      
  -   private Timer schedule(Long duration, Date expiration, Long intervalDuration, Asynchronous asynchronous)
  +   private Timer scheduleWithTimerService(TimerSchedule schedule, Asynchronous asynchronous)
      {
  -      return new TimerProxy( scheduleWithTimerService(duration, expiration, intervalDuration, asynchronous) );
  -   }
  -
  -   private Timer scheduleWithTimerService(Long duration, Date expiration, Long intervalDuration, Asynchronous asynchronous)
  +      if ( schedule.getIntervalDuration()!=null )
      {
  -      if (intervalDuration!=null)
  +         if ( schedule.getExpiration()!=null )
         {
  -         if (expiration!=null)
  +             return timerService.createTimer( schedule.getExpiration(), schedule.getIntervalDuration(), asynchronous );
  +         }
  +         else if ( schedule.getDuration()!=null )
            {
  -             return timerService.createTimer(expiration, intervalDuration, asynchronous);
  +             return timerService.createTimer( schedule.getDuration(), schedule.getIntervalDuration(), asynchronous );
            }
            else
            {
  -             return timerService.createTimer(duration, intervalDuration, asynchronous);
  +            return timerService.createTimer( 0l, schedule.getIntervalDuration(), asynchronous );
            }            
         }
  -      else if (expiration!=null)
  +      else if ( schedule.getExpiration()!=null )
         {
  -          return timerService.createTimer(expiration, asynchronous);
  +          return timerService.createTimer( schedule.getExpiration(), asynchronous );
         }
  -      else if (duration!=null)
  +      else if ( schedule.getDuration()!=null )
         {
  -          return timerService.createTimer(duration, asynchronous);
  +          return timerService.createTimer( schedule.getDuration(), asynchronous );
         }
         else
         {
  -         throw new IllegalArgumentException("TimerServiceSchedule is empty");
  +         return timerService.createTimer(0l, asynchronous);
         }
      }
      
  
  
  
  1.1      date: 2007/05/31 21:05:28;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/core/TimerSchedule.java
  
  Index: TimerSchedule.java
  ===================================================================
  /**
   * 
   */
  package org.jboss.seam.core;
  
  import java.io.Serializable;
  import java.util.Date;
  
  /**
   * A "schedule" for a timed event executed by
   * the EJB timer service or some other timer
   * service which supports delayed and/or periodic
   * timed events.
   * 
   * @author Gavin King
   *
   */
  public class TimerSchedule implements Serializable
  {
     private Long duration;
     private Date expiration;
     private Long intervalDuration;
     
     Long getDuration()
     {
        return duration;
     }
     
     Date getExpiration()
     {
        return expiration;
     }
     
     Long getIntervalDuration()
     {
        return intervalDuration;
     }
     
     /**
      * @param duration the delay before the event occurs
      */
     public TimerSchedule(Long duration)
     {
        this.duration = duration;
     }
  
     /**
      * @param expiration the datetime at which the event occurs
      */
     public TimerSchedule(Date expiration)
     {
        this.expiration = expiration;
     }
  
     /**
      * @param duration the delay before the first event occurs
      * @param intervalDuration the period between the events
      */
     public TimerSchedule(Long duration, Long intervalDuration)
     {
        this.duration = duration;
        this.intervalDuration = intervalDuration;
     }
  
     /**
      * @param expiration the datetime at which the first event occurs
      * @param intervalDuration the period between the events
      */
     public TimerSchedule(Date expiration, Long intervalDuration)
     {
        this.expiration = expiration;
        this.intervalDuration = intervalDuration;
     }
  
     TimerSchedule(Long duration, Date expiration, Long intervalDuration)
     {
        this.duration = duration;
        this.expiration = expiration;
        this.intervalDuration = intervalDuration;
     }
  
     TimerSchedule() {}
     
     public static final TimerSchedule ONCE_IMMEDIATELY = new TimerSchedule();
     
  }
  
  



More information about the jboss-cvs-commits mailing list