[ 
https://issues.apache.org/jira/browse/PIVOT-535?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12880664#action_12880664
 ] 

Appddevvv commented on PIVOT-535:
---------------------------------

I've attached a design spec below. The posted code is a starting point but not 
a final answer.  More thinking is needed around automatic unsubscribing. The 
issue of unsubscribing can be mostly handled using weak listeners *inside* the 
proposed general purpose message listener class. Weak listeners are safe inside 
the proposed message listener class associated with the annotation but robust 
thinking and examples will help flush out all use cases.  They are safe as 
proposed but  you can do without them with a little bit more code, they were an 
easy answer to the unsubscription problem to get a first cut out.

Pivot team, if you decide to keep this open, its okay if this gets bumped down 
on the priority list. I'll update the starting points that I sent out and post 
them.



Here's the spec:

Design Intent: To reduce code  and improve line-of-sight into client intent 
when registering for application context messages in java. The motivation was 
based on the dev's list recommendation to look at pivot's message management 
capabilities and potentially use them, if appropriate, for decoupling sender 
and receivers. This was in response to some comments about EventBus somewhere 
in early 2010. The intent to make this easier in java is the same as allowing 
listener registration in the serializer in script. In some cases, its 
significantly easier and cleaner.

Examples:
Change code like this:

public class MyClass ... { 

....
   ApplicationContext.subscribe(MyTopic.class, new 
ApplicationContextMessageListener<MyTopic>() {
  @Override
   public void sentMessage(MyTopic arg) {
        ....
        justDoIt(arg);
        ...
   }

  public void justDoIt(MyTopic arg) {
      ....
   }
} ;

to:

public class MyClass ... {

  public MyClass() {
     MessageListenerAnnotationProcessor.process(this);
  }

  @MessageListener
  public void justDoit(MyTopic arg) {
     ...
   }
}

If you have more than one topic you are subscribing to within a class, the 
intent becomes more clear within that class. If you subclass the serializer, 
you can  process this annotation on any object transparently but otherwise the 
annotation processor has to be called to scan the class. In the above example, 
it is shown being used in the constructor.

Design points:
a) Allow listener registration using annotations on a method.

b) Allow the option of strong or weak subscription. This refers to the proposed 
general message listener and *not* within the ApplicationContext itself. 
Default is weak. Most importantly, weak listener bad behavior is completely 
managed so it is less of an issue than with using inner anonymous classes. 
That's a plus. Also, strong references are not always perfect if you forget to 
unsubscribe. Both strong and weak have beneficial use cases and the code is 
nearly identical. Note that in the current form, you need to use a weak 
reference to the target object to allow it to unregister itself but that's 
because the starting point code examples were written quickly.

c) Allow the specification of the listener type when the annotation is 
processed. This allows you to create your own listener and move additional 
filtering and conditional logic out of your class and into the message handler. 
This makes it easier to address filtering. Class-level filtering can be fairly 
large-grained. In addition, it allows transparent add-ons and extensions to be 
added that are outside the scope of pivot's focus such as message logging, 
interception, filtering,  queue control and proxying. This also allows other 
instantiation and initialization methods to be employed.

d) Support minimal reply-request behavior. This is also a common use of 
messages and the code is identical except for 2 lines in the implementation. 
This allows the user to write a method like below and  translate messages 
without further reference to the application context. In fact, there are no 
references to the application context, message listeners or other pivot 
elements.

public class MyClass ... {

   @MessageListener(requestReply=true)
   public OutputMessage process(InputMessage message) {
       ....
       return outputMessage;
   }

}


Alternatives:
a) Perform message listening in script. This reduces code and in some cases, 
improves clarity on intent. However, this is not a java based solution and some 
classes may not have the benefit of being created in the serializer.

b) Keep coding by hand with anonymous classes. This approach works and is fine 
but part of the recommendation is to make this easier and more clear.

c) Use other libraries like EventBus. This is a good option, but the idea was 
to use more pivot features and decrease external library dependence, where 
possible. EventBus has more fine-grained filtering behavior but this may or may 
not be critical to a pivot application. For simple uses, pivot's is fine and 
appropriate. Easier message registration is a plus. The two systems can be 
easily bridged if need be.

Pros:
a) Clearer client intent. 

b) Less java coding. This is similar in concept to the benefits of using of 
script in the serializer.


Cons:
a) More code in the pivot base to maintain.

b) Uses reflection (all internally). Some think this should be avoided in 
general.

c) Without ApplicationContext enhancements, you need to use weak listeners 
inside the specialized message listener class. While the implementation would 
be safe, it requires dealing with weak listener perceptions.

d) If you only have 1-2 message listener classes in your application, this is 
not reducing alot of complexity.


> Add a @MessageListener annotation and an annotation processor for application 
> context message listener
> ------------------------------------------------------------------------------------------------------
>
>                 Key: PIVOT-535
>                 URL: https://issues.apache.org/jira/browse/PIVOT-535
>             Project: Pivot
>          Issue Type: Improvement
>            Reporter: Appddevvv
>
> Add a message listener annotation and a static method for annotation 
> processing to automatically enroll instance/methods in application message 
> handling.
> I have the classes that I can submit as a starting point. They allow weak and 
> strong references as well as optional request-reply semantics.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to