2 Replies Latest reply on Oct 10, 2011 11:11 AM by Martin Frey

    Best design practice for a scheduler use case

    Sam H Newbie

      Hi guys,


      I need some advice regarding the best practice to implement the following use case.


      Say, if I used Quartz to implement a scheduler that can select what tasks to run at a scheduled time regularly.
      All the tasks have to do is implement an interface, say Task. At scheduled time, the scheduler simply runs the
      execute() method of the Task interface.


      Now if I want to upload tasks packaged within a jar file to the application and have it become visible to scheduler automatically at runtime, whats the best design to go about these?


      I am thinking of using listeners. Each implementation class of the Task interface will be a application scope
      component that somehow registers itself with the application once uploaded.


      What do you think?


      Thanks


      Sam

        • 1. Re: Best design practice for a scheduler use case
          Sam H Newbie

          I think what I need is the ability to register a seam component (which implements the Task interface) dynamically at runtime.


          After some digging, one hopeful link I found is http://seamframework.org/98760.lace


          Will try this out latter and post back what I found.


          Thanks


          Sam

          • 2. Re: Best design practice for a scheduler use case
            Martin Frey Newbie

            Hi
            here is some code i wrote once so i'm able to declare jobs to run in the components.xml. Probably this can help you.


            Feel free to use it and feedback is appreciated in this case also ;)



            /**
             * The ScheduleController allows the declarative scheduling of quartz jobs
             * through the components.xml file. A job needs to implemented the SeamQuartzJob
             * interfaces
             * 
             * @author Martin Frey
             * 
             */
            @Name("org.mfrey.ch.seam.scheduleController")
            @Scope(APPLICATION)
            @AutoCreate
            @Startup
            @Install(value = false, precedence = Install.FRAMEWORK, dependencies = { "org.jboss.seam.async.dispatcher" })
            @BypassInterceptors
            public class ScheduleController implements Serializable {
            
                 /** The log. */
                 private static Log log = LogFactory.getLog(ScheduleController.class);
            
                 private static final long serialVersionUID = 7609983147081676186L;
            
                 private Map<String, String> jobs;
            
                 public Map<String, String> getJobs() {
                      if (jobs == null) {
                           jobs = new HashMap<String, String>();
                      }
                      return jobs;
                 }
            
                 @Create
                 public void scheduleTimer() {
                      Calendar cal = Calendar.getInstance();
                      cal.add(Calendar.SECOND, 10);
                      Date startDate = cal.getTime();
                      log.debug("Starting jobs with a delay of 10 sec");
                      for (Entry<String, String> jobEntry : getJobs().entrySet()) {
                           try {
                                log.debug("Starting " + jobEntry.getKey() + " -> "
                                          + jobEntry.getValue());
                                SeamQuartzJob job = (SeamQuartzJob) Component
                                          .getInstance(jobEntry.getKey());
                                job.createQuartzTimer(startDate, jobEntry.getValue());
                           } catch (Exception e) {
                                log.error("FAILED", e);
                           }
                      }
                 }
            
                 public void setJobs(Map<String, String> jobs) {
                      this.jobs = jobs;
                 }
            
            }





            /**
             * Interface for quartz jobs runnable with the schedule controller
             * 
             * @author Martin Frey
             * 
             */
            public interface SeamQuartzJob extends Serializable {
            
                 @Asynchronous
                 public QuartzTriggerHandle createQuartzTimer(@Expiration Date when,
                           @IntervalCron String interval);
            }





            <component class="org.mfrey.ch.seamextensions.quartz.ScheduleController"
                      name="org.mfrey.ch.seam.scheduleController">
                      <property name="jobs">
                           <key>someJob</key>
                           <value>0 0/2 * * * ?</value>
                           <key>someOtherJob</key>
                           <value>0 0 23 * * ?</value>
                      </property>
                 </component>