9 Replies Latest reply on May 8, 2010 6:36 AM by cjalmeida

    Proper decoupling of Event producer and observer?

    drill

      I am trying to use Events in a web application to do a time consuming task. I am firing the event in a RequestScoped bean, thinking that the request will finish and the task will carry on without the user having to wait for it. When I found it not working, the request would hang waiting for the event observer to finish, I did some googling and I found jjviana's blog:



      There is however another, more subtle, form of coupling taking place:  event dispatching usually happens in the same thread that fired the event. Event observers can perform some long-running tasks upon receiving an event, which will block this thread. This may or may not be a problem, depending on where the event proucer thread is located. If this thread is for instance a GUI event thread or a HTTP request processing thread then the end user may be forced to wait for a response from the application while a slow operation is taking place.

      His solution was to implement a JMS layer in his application. I do feel this is a bit of a big overhead, and that Events feel a bit unfinished when they are not really decoupled.


      Any other way around this? Is this functionality planned to be in CDI, or perhaps Seam3?

        • 1. Re: Proper decoupling of Event producer and observer?
          nickarls

          Asynchronous events was in a previous draft of JSR-299 and they will probably be back as an extension. The request scoped is ThreadLocal based, though so there will have to be some magic involved if we want to continue processing request scoped stuff after the http request has ended. I don't recall how this was handled in Seam 2

          • 2. Re: Proper decoupling of Event producer and observer?
            cjalmeida

            IIRC, the @Asynchronous interceptor serialized the current context and executed the method in a new Thread. Inside the async method, you only have access to beans in the current context and Application context. Makes sense since any conversations and sessions might have been destroyed.


            Back to the original question, for now, if your event does something time-consuming, you might think of wrapping it in a new Thread.

            • 3. Re: Proper decoupling of Event producer and observer?
              cjalmeida

              I used it for reliable async REST calls, which prompted me to use Quartz as the async engine for persistence. Had to deal with XA transactions, Quartz arcane configurations, etc. Bad idea, I ended up re-implementing my own version of JMS.


              JMS, bundled in most Java EE servers, is not that heavyweight for what it provides and has pretty strong implementations. I'd be nice if Seam 3 Async services were implemented on top of it.

              • 4. Re: Proper decoupling of Event producer and observer?
                pmuir

                We plan to have support for this in Seam 3. You could check out our prototype

                • 5. Re: Proper decoupling of Event producer and observer?
                  kenglxn

                  The prototype can also be found via Anonymous  svn here Prototype

                  • 6. Re: Proper decoupling of Event producer and observer?
                    phantasmo

                    When I read about events being synchronous in the blog mentioned by the original poster, I must say I was puzzled. Isn't it very strange not to support asynchronous events? How come they were removed from the spec?
                    I mean, don't get me wrong, I'm just wondering...
                    Anyway, good to hear we'll have them in Seam 3.

                    • 7. Re: Proper decoupling of Event producer and observer?
                      kapitanpetko

                      Cloves Almeida wrote on May 04, 2010 20:03:


                      JMS, bundled in most Java EE servers, is not that heavyweight for what it provides and has pretty strong implementations. I'd be nice if Seam 3 Async services were implemented on top of it.


                      IMHO, async support is one of that things that works well in Seam 2. By changing the dispatcher you can use a thread pool, EJB timer service or Quartz as the underlying engine. JMS works well, but you have to define queues just for executing something on a different thread, and it might be unavailable in Tomcat, etc. (use 'real' app servers, I know, but those are really not that great). Too much overhead for async messaging in the same JVM. So native (no-JMS) async events are definitely a good thing to have.


                      BTW, if you are using JEE 6, you can simply use the native @Asynchronous methods.

                      • 8. Re: Proper decoupling of Event producer and observer?
                        pmuir

                        Bojan Tomic wrote on May 05, 2010 20:34:


                        When I read about events being synchronous in the blog mentioned by the original poster, I must say I was puzzled. Isn't it very strange not to support asynchronous events? How come they were removed from the spec?
                        I mean, don't get me wrong, I'm just wondering...
                        Anyway, good to hear we'll have them in Seam 3.


                        Nikolay points at the answer - there was overlap with the EJB spec (which needed resolving, which takes time), and it was decided that this was something that can be a portable extension, we should defer it for now.

                        • 9. Re: Proper decoupling of Event producer and observer?
                          cjalmeida

                          My specific problem was about reliability - I needed to POST some data to some remote web server asynchronously which might be down for any reason. But since it was important transaction data, I wanted to make sure the method will be executed (and retried if failed) even in case of container failure. What I needed was, in fact, a


                          @ReliableTransactionalAsynchronous(queue,retryAfterSeconds)



                          But back then, JBoss implementation of EJBTimer was buggy, so I used Quartz - which is a pain in the arse to configure for transactional persistent jobs.