4 Replies Latest reply on May 8, 2009 1:06 AM by swd847

    Asynchronous event for every logged user

    maciekpazur

      I have a following problem:


      My application lets users send and receive simple messages. I would like my application to inform user when they've received a new message. To achieve this I want user to query the database every 5 minutes. I created a class which is to raise timed events:



      @Name("eventDispatcher")
      @Scope(ScopeType.APPLICATION)
      @Startup
      public class EventDispatcher {
      
           @Create
           public void init() {
                Events.instance().raiseTimedEvent("test4",
                          new TimerSchedule(3000L, 8000L));
           }
      
           @Remove
           public void remove() {
           }
      
      }



      And added a simple observer method to User. For the time being it shall only increment a counter.



      @Observer("test4")
           @Asynchronous
           public void test4() {
                msg++;
           }



      Unfortunately, this doesn't work - the counter remains 0 all the time.
      I have two questions:



      1. Is it  (raising and observing timed events) the best way to achieve my goal? If so, what shall I fix in my code?

      2. Otherwise, what is the proper way to do it?



      Thanks for any help.

        • 1. Re: Asynchronous event for every logged user
          kapitanpetko

          Seems an OK way to do it. Not sure if it is 'the best way', but really depends on what you are trying to achieve (who do you inform the user: via the UI, with email?) You could try registering a job directly (using Asynchronous) and have your job method raise the event, but should be essentially the same thing.


          As for debugging your code, you should first check whether your init methods is actually being called: put some logging in there. Then try to remove the Asynchronous annotation from your test4 method and check if it is called when an event is raised. Btw, if your observer component is an EJB, you should annotate your interface declaration with Asynchronous, not the implementation method.


          HTH


          • 2. Re: Asynchronous event for every logged user
            swd847

            Sorry, events don't work like that.


            Events are run on a per-request basis, so for example if one user get a session expired event or similar only components that 'belong' to that user will receive the event (belong is probably not the right word, but anyway).


            You probably want an a4j:poll in the ui layer combined with a cached list of messages that expire every 5 minutes (I am assuming you only want to query every 5 minutes to reduce db load), or something similar.

            • 3. Re: Asynchronous event for every logged user
              maciekpazur

              Thank you very much. a4j:poll is almost what I've been looking for. The problem is when user opens a new page the interval is counted from the very beginning. Therefore when user changes pages more often than every five minutes he won't be informed.


              Should I use a4j:poll in a different way? Or maybe solve the problem with a totally different method?


              Thanks in advance

              • 4. Re: Asynchronous event for every logged user
                swd847

                Whenever you render a new page check for messages. If you are worried about DB load store the messages in a cache node with a 5 minute expiry.