4 Replies Latest reply on Sep 10, 2013 5:02 PM by mbickel

    How do I use Richfaces' Push from a EJB Timer?

    mbickel

      I've been trying to setup a user notification/reminder functionality in my application and decided to try out <a4j:push> for this. The idea is that application code would start an EJB timer and upon expiring the timer, the bean would publish whatever it was given as additional info as a push message to a user specific topic.

       

      The environment is Jboss 7.1.1 with RF-4.3.2 and Seam-2.3 (with a switch to CDI on the horizon).

       

      So the meat looks like this:

      @Name("notificationManager")
      @Scope(ScopeType.STATELESS)
      @Stateless
      public class NotificationManager {
          private static final String ROOT_TOPIC = "userNotifications";
          private static final Logger LOGGER = LoggerFactory.getLogger(NotificationManager.class);
      
          @Resource
          private TimerService timerService;
      
          public void queue(NotificationSpec spec) {
              timerService.createTimer(spec.getTimeout(), (String) spec.asType(String.class));
          }
      
          @Timeout
          public void push(Timer timer) {
              try {
                  TopicKey key = new TopicKey(ROOT_TOPIC, "me");
                  Topic t = TopicsContext.lookup().getOrCreateTopic(key);
                  t.publish(key, timer.getInfo());
              } catch (MessageException e) {
                  LOGGER.error(e.getMessage(), e);
              }
          }
      }
      
      

       

      Now, I'm aware of Re: AJAX Push Error - "Service Tracker has not been initialized" which I'm getting as a response to a timed-out Timer as well. Surely the EJB doesn't run with a FacesContext or the web archive classloader active (NotificationManager is part of a library JAR inside my EAR deployment), which explains the exception. I do have org.richfaces.push.initializeOnStartup set to "true" in my web.xml.

       

      I've verified that the concept works by publishing a message from the (conversation scoped) bean in response to a button click directly, which showed up just fine.

       

      My question here is: do you have a suggestion to avoid switching this to JMS and go with the TopicsContext? Setting up JMS just for this feature is a pain I'd rather avoid.

        • 1. Re: How do I use Richfaces' Push from a EJB Timer?
          bleathem

          Try firing a CDI event from from your EJB timer, and listening to that in a WAR class that publishes the push notification.  A nice separation of concerns.

          1 of 1 people found this helpful
          • 2. Re: How do I use Richfaces' Push from a EJB Timer?
            mbickel

            Yeah, that would be great. I've already split the code into a session scoped manager and a "delay element", a stateless session bean that houses the @Timeout method. So triggering a "wakeup" event the SFSB manager bean can respond to sounds perfect.

             

            But I have another question that I can't wrap my head around: the timer information includes the user principal name that caused the timer start. I want to deliver the event only to the manager attached to a session for this user. If there isn't one, I want the @Timeout method or a fallback event handler to persist the event information until the bean becomes available. The SFSB will have an appropiate @PostConstruct method to read past notifications and push them to the client. I haven't found a way to make this work with Seam Events, do you have an idea to do this with CDI?

            • 3. Re: How do I use Richfaces' Push from a EJB Timer?
              bleathem

              Matti Bickel wrote:

               

              I want the @Timeout method or a fallback event handler to persist the event information until the bean becomes available.

               

              Sounds like you pulled that requirement out of the JMS spec to me...  Setting up JMS isn't *that* bad - at least it's one time task.

              • 4. Re: How do I use Richfaces' Push from a EJB Timer?
                mbickel

                Yeah, I realized the requirement sounded exactly like a durable topic or maybe even a queue. My opposition is mainly based on not wanting such a big system with it's own terminology and concepts for this task. But yeah, I'll bite the bullet.