5 Replies Latest reply on Oct 5, 2011 7:32 AM by lfryc

    Push CDI Integration - API design and thougts

    lfryc

      Hi guys,

       

      Push CDI integration got to the state that we have two proposals how it's API should look like:

       

      1. use CDI Event<PushMessage> mechanism directly
      2. use custom PushEvent<Payload> interface

       

      Event<PushMessage>

      @Inject
      Event<PushMessage> event;
      
      @Inject
      @Push("subtopic@topic")
      TopicKey topic;
      
      
          method() {
              event.fire(new PushMessage(topic, "some message payload"));
          }
      

       

      PushEvent<Payload>

       

      @Inject
      @Push("subtopic@topic")
      PushEvent<String> event;
      
      method() {
          event.fire("some message payload");
      } 
      

       

       

      Just note that we can't use Event<Payload> since with CDI 1.0 we are not able to read qualifier, that's why (1) have topic bundled with message.

       

      Further details:

      https://issues.jboss.org/browse/RF-11110

        • 1. Re: Push CDI Integration - API design and thougts
          lfryc

          Both of options has its advantages:

           

          Event<PushMessage>

          • + clean and simple implementation using basic CDI concepts
          • + you can observe all PushMessage-s in system
          • - verbose API
          • - message payload not type-safe PushMessage(TopicKey, Object)

           

          PushEvent<Payload>

          • + clean and simple API
          • + type-safe message payload
          • + better decoupling
            • event's payload is not dependent on Push
          • + simple transition to CDI 1.1 Event mechanism (once available)
            • Event<Payload>
          • - complex implementation
            • needs to use CDI Extension
            • need to re-publish messages onto regular CDI Event Bus
          • 2. Re: Push CDI Integration - API design and thougts
            bleathem

            Hi Lukas, thanks for summarizing the API options.

             

            One could simplify Option 1 further to:

             

            Event<PushMessage>

            @Inject
            Event<PushMessage> event;
            
                method() {
                    event.fire(new PushMessage("subtopic@topic", "some message payload"));
                }
            

             

            and have equivalent levels of type safety with the "PushEvent<Payload>" option.

             

            I see the biggest advantage of this syntax is that it is fully based on CDI, and devs can listen to the events and act on them.  The tradeoff is publishing events is one class more complex, but listenening top the events is trivial.  If we try to publish events with "PushEvent<Payload>" option, we will either @Observes different classes than we are firing, or we will lose topic information.

             

            In short, the biggest turn-off for me of the "PushEvent<Payload>" syntax is that it isn't CDI, and I might as well just use the static factory syntax if I'm not going to use CDI.

            • 3. Re: Push CDI Integration - API design and thougts
              lfryc

              ...  If we try to publish events with "PushEvent<Payload>" option, we will either @Observes different classes than we are firing, or we will lose topic information.

               

              In short, the biggest turn-off for me of the "PushEvent<Payload>" syntax is that it isn't CDI, and I might as well just use the static factory syntax if I'm not going to use CDI.

               

              In option PushEvent<Payload> we are surely losing information about topics, but I think that's not to the detriment of CDI messaging - topic is information only for RichFaces messages bus, once you will process it, application should not rely on that. The real value is inside payload object and its type.

               

              On the other hand, with PushMessage concept, you can reuse standard CDI eventing system simply, but you are working with PushMessage, which tightly couples you to the framework which defines it.

               

              The problematic with PushMessage's not being type-safe is that regarding to CDI, PushMessage can't be type-parametrized, degrading to PushMessage(TopicKey, Object) (overloaded as PushMessage(String, Object)).

              • 4. Re: Push CDI Integration - API design and thougts
                lfryc

                There is also one option, which is following standard CDI Events mechanism:

                 

                 

                @Inject
                @Push("some@topic")
                Event<Payload> event;
                
                method() {
                     event.fire(new Payload());
                }
                

                 

                It counts with relying on extensions and with fact that @Push qualifier has binding parameters (as oposed to non-binding).

                 

                Implementation is as follows:

                • no event observer for @Push qualified events is registered out-of-the-box
                • event observer is created dynamically by extension
                  • thanks to knowledge of topics created
                  • and this knowledge may be obtained either by...
                    • scanning beans for @Push qualified injection points
                    • or from the list of created topics (obtained from TopicsContext)
                  • then CDI's ObserverMethod can be created dynamically for each topic separately

                 

                This concept has been suggested by Jozef Hartinger.

                • 5. Re: Push CDI Integration - API design and thougts
                  lfryc

                  The last solution has one pitfall - @Push can't dynamically contructed as described in [1, Ch. 11 Sec. 5. Event qualifiers with members] using AnnotationLiteral.

                   

                  I think when user needs to dynamically create topics/subtopics, then he can fallback to TopicsContext#publish.

                   

                  [1] http://docs.jboss.org/weld/reference/1.0.0/en-US/html/events.html#d0e3951