5 Replies Latest reply on Apr 22, 2010 4:55 PM by ssarver

    Rerender dataTable from Quartz async call

    ssarver

      How can I rerender a dataTable that displays the instances of an entity bean after making changes
      to the entity bean in a Quartz async call?  Is there a way for me to lookup the Seam component
      registered as @Name(hostHome) from within the Quartz async call and invoke the updateTable method
      to force the rich:dataTable to rerender using a4j:push?  Is the following approach correct?  Is there
      a better way?
       
      Pseudo code:




      import java.util.EventListener;
      import java.util.EventObject;
      import org.ajax4jsf.event.PushEventListener;
      
      @Name("hostHome")
      public class HostHome extends EntityHome<Host> {
        private PushEventListener listener;
      
        public void addListener(EventListener listener) {
          if (this.listener != listener) {
            this.listener = (PushEventListener) listener;
          }
        }
      
        public updateTable() {
          listener.onEvent(new EventObject(this));
        }
      }
      
      






      <rich:dataTable value="#{hostList.resultList}" var="host" id="hostTable">
      ...
      </rich:dataTable>
      
      <a4j:push eventProducer="#{hostHome.addListener}" id="push"
                  limitToList="true" 
                     reRender="hostTable"/>
      



        • 1. Re: Rerender dataTable from Quartz async call
          asookazian

          Not sure, but I'd like to know the best practice for this scenario...

          • 2. Re: Rerender dataTable from Quartz async call
            gaborj

            The lookup of Seam comp from Quartz job works like a mercedes.


            If your point is how to trigger the end of the asynch job, then I have s.g. in mind. Similar in concept but an other option can be using Remoting i.e. annotate your component @WebRemote, access your method from your custom JS method and rerender the table from this when finished.


            Returning processing status (e.g. how many records are processed already and how much time it took) you can little more fine tune your remote call interval depending on the status of your asynch job.


            It is similar if you set your interval="#{dynamicPushIntervalBasedOnWeightAndStatusOfJob}" in the a4j:push...


            The more your statistical dispersion of asynch processing time the more it worth to implement the dynamic interval. In case of simple asynch logic it does not make much difference to the simple solution with static interval.


            Some intermediate solution can be if you can approximate your job processing time needs e.g. before each schedule if needed...

            • 3. Re: Rerender dataTable from Quartz async call
              ssarver



              If your point is how to trigger the end of the asynch job, then I have s.g. in mind.

              What is s.g.?

              • 4. Re: Rerender dataTable from Quartz async call
                gaborj

                s.g. is acronym for something. Actually, the thing I detailed in my post above...
                Anyway, could you solve this in your way? Is it working? Are you happy with it?...

                • 5. Re: Rerender dataTable from Quartz async call
                  ssarver

                  I found a working solution.
                  I added the event listener methods above to a listenerService bean with application scope.
                  I added the @Observer to the updateTable method.  In the Quartz async call, I raise an event using:



                  Events.instance().raiseEvent("remoteJobs.updated");




                  @Name("listenerService")
                  @Scope(ScopeType.APPLICATION)
                  public class ListenerService {
                    @Logger 
                    private Log log;
                    private PushEventListener listener;
                  
                    public void addListener(EventListener el) {
                      if (listener != el) {
                        listener = (PushEventListener) el;
                      }
                    }
                    
                    @Observer("remoteJobs.updated")
                    public void renderDataTable() {
                      try {
                        if (null != listener) { 
                          listener.onEvent(new EventObject(this));
                        }
                      }
                      catch (Exception e) {
                        e.printStackTrace();
                      }
                    }
                  }





                       <a:region>
                         <h:form>
                           <a:push reRender="hostTable, ds" eventProducer="#{listenerService.addListener}" interval="5000"/>
                         </h:form>
                       </a:region>