5 Replies Latest reply: Oct 5, 2011 7:32 AM by Lukáš Fryč RSS

Push CDI Integration - API design and thougts

Lukáš Fryč Master

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
    Lukáš Fryč Master

    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
    Brian Leathem Master

    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
    Lukáš Fryč Master

    ...  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
    Lukáš Fryč Master

    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
    Lukáš Fryč Master

    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