You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@directory.apache.org by Alex Karasulu <ao...@bellsouth.net> on 2004/09/22 07:35:02 UTC

[seda] event notifier pattern clarification

This is in reference to the Event Notifier pattern described here:

http://www.dralasoft.com/products/eventbroker/whitepaper/

Trustin, Enrique, Noel and I were discussing this on IRC.  Actually we
were discussing how to handle situations were we need to change the way
we route in complex ways sometimes based on:

 o event type (normal for pattern)
 o event filters 
 o event properties/attributes 
 o extraneous logic

Any combination of the above can be used.  There were comments made
about the weaknesses of this pattern specifically where EventType is
used to determine how to route an event to Subscribers.  I agreed but
soon realized that I'm very wrong and this email will tell you why.

The most important point to make is there are two dimensions to
controlling routing in the standard pattern.

(i)  event type
(ii) filters

The event type can totally be turned of by making subscribing for the
root event type EventObject.  So one can subscribe Subscribers for all
events and use logic within Filters to determine whether or not to
inform() the Subscriber.  The logic in the filter can be as dynamic as
you want it to be.  It can check EventObject properties or use
extraneous parameters to determine if the Subscriber should be
notified.  We can check the time of day, type of service event is
associated with, and client specific information if that's what we want
to use in making the routing decision.

So at the end of the day we have all the expressivity we need in this
pattern which as stood the test of time.  However Trustin brought some
interesting ideas to the table.  He spoke about transformations of
Events before informing a Subscriber.  This got me thinking; this is
another dimension for controling routing decisions.

I also had an idea of my own.  I thought about adding routing advice. 
Advice would prune, and/or augment the Subscribers consulted, it would
also transform the event if necessary before delivering it to
Subscribers.  This would extend the routing control of the pattern
further than it has gone before (I think).  Perhaps this has already
been done.

Here's how routing Advice could be administered to the router:

interface EventRouter {
...
    apply(Advice);
}

Here's how Advice would look:

interface Advice {
...
    Subscription[] getSubscriptions(Event, Subscriptions[]);
    Event getEvent(Event);
}

Advice can be registered on the basis of event type too.  It does not
hurt to do this at all if we just take the root of the event heirarchy
then all events will be checked for advice.

Basically if there is advice for routing then the standard set of
Subscriptions are ignored.  Only the ones returned by the Advice are
used to inform.  Secondly the EventObject used to inform is transformed
before the inform().  The EventObject may not have changed, it can just
be returned as is if transformation via 'cloning' is not in effect.

WDYT?

Alex



Re: [seda] event notifier pattern clarification

Posted by Trustin Lee <tr...@gmail.com>.
I'm working on this issue (DIRSEDA-12), and I think I found a better solution.

The problem here was 'bypassing encoder and decoder is impossible for
current event routing model', and it was solved by RoutingAdvice, but
it looked somewhat messy; we had to have three(!) control factors! So
I tried to make them to two:

1. EventFilter: event types are also handled here by EventTypeFilter
utility class.
2. Source Subscriber: the subscriber who fired the event.

This two factor elegantly solves all of our routing issues completely
because it makes us to control the routing by 'source subscriber'.
'Who' fired this event?  It is probaly most important information!

and, here is my suggesting API:

public interface EventRouter {
       SubscriberContext add(String name, Subscriber subscriber);
       void remove(String name);
}

public interface SubscriberContext {
       String getName();
       void subscribe(String eventSourceName, Filter eventFilter);
       void unsubscribe(String eventSourceName, Filter eventFilter);
       boolean publish(SessionEvent event);
       SubscriberMonitor getMonitor();
       void setMonitor(SubscriberMonitor monitor);
}

public interface Subscriber extends EventListener {
       void inform(SubscriberContext ctx, SessionEvent event);
}

public interface Filter {
       static Filter ALL = new Filter() {
               public boolean accept(SessionEvent event) {
                       return true;
               }
       };

       boolean accept(SessionEvent event);
}

And here is the usage:

EventRouter er = ...;
SubscriberContext ctx;

er.add("listener", tcpLIstenerManager);
ctx = er.add("input", inputListenerManager);
ctx.subscribe("listener", Filter.ALL);
...

public class MySubscriber implements Subscriber {

   public void inform(SubscriberContext ctx, SessionEvent event) {
       // do something with event
       ....
       ctx.publish(replyEvent);
   }
   ....
}

HDYT?

I'm already working on this, and you can see it in
'trustin_api_redesign' branch now although there are a lot of
compilation errors in the implementation part.

Cheers,
Trustin Lee

Re: [seda] event notifier pattern clarification

Posted by Alex Karasulu <ao...@bellsouth.net>.
Hey before my lights go out here's the goods:

http://svn.apache.org/viewcvs.cgi?rev=47040&root=Apache-SVN&view=rev

Change it and patch at will :-).

Cheers,
Alex

On Wed, 2004-09-22 at 05:05, Trustin Lee wrote:
> Alex and I talked alot on IRC and I agree with his opinion completely.
> 
> > interface Advice {
> > ...
> >     Subscription[] getSubscriptions(Event, Subscriptions[]);
> >     Event getEvent(Event);
> > }
> 
> This API has two problems:
> 
> 1. Using array implies very frequent allocation of arrays which occurs
> whenever EventRouter gets an advice.  So I suggest to use some
> reusable object.
> 
> 2. EventRouter must call two methods (getSubscriptions and getEvent)
> for each event, and it can imply duplicate calculation on the same
> event.  For example, let's assume that there is an advice that
> transforms the specific type of event and filters its subscriptions,
> then the 'if' block which identifies the type of the event is executed
> twice, and it is an wate of time.
> 
> so.. I suggest this method:
> 
> public class RouterAdvice {
> 	// assume getters and setters exist
> 	Event event;
> 	List subscriptions;
> }
> 
> public interface RouterAdvisor { // RouterAdvice in Alex's code
> 	void getAdvice(RouterAdvice);
> }
> 
> RouterAdvisor.getAdvice() gets both event and subscriptions and then
> sets back the transformed (or not transformed) event and modifies the
> subscription list.
> 
> the advantage of this method is:
> 
> 1. RouterAdvice is reused (using threadlocal? not sure about this), so
> there is less overhead on GC.
> 
> 2. Can get RouterAdvice in a single method invocation, so there is no
> duplicate code.
> 
> but don't you think the name 'getAdvice' is strange?  It does not have
> a return type. :)
> 
> Trustin


Re: [seda] event notifier pattern clarification

Posted by Trustin Lee <tr...@gmail.com>.
Alex and I talked alot on IRC and I agree with his opinion completely.

> interface Advice {
> ...
>     Subscription[] getSubscriptions(Event, Subscriptions[]);
>     Event getEvent(Event);
> }

This API has two problems:

1. Using array implies very frequent allocation of arrays which occurs
whenever EventRouter gets an advice.  So I suggest to use some
reusable object.

2. EventRouter must call two methods (getSubscriptions and getEvent)
for each event, and it can imply duplicate calculation on the same
event.  For example, let's assume that there is an advice that
transforms the specific type of event and filters its subscriptions,
then the 'if' block which identifies the type of the event is executed
twice, and it is an wate of time.

so.. I suggest this method:

public class RouterAdvice {
	// assume getters and setters exist
	Event event;
	List subscriptions;
}

public interface RouterAdvisor { // RouterAdvice in Alex's code
	void getAdvice(RouterAdvice);
}

RouterAdvisor.getAdvice() gets both event and subscriptions and then
sets back the transformed (or not transformed) event and modifies the
subscription list.

the advantage of this method is:

1. RouterAdvice is reused (using threadlocal? not sure about this), so
there is less overhead on GC.

2. Can get RouterAdvice in a single method invocation, so there is no
duplicate code.

but don't you think the name 'getAdvice' is strange?  It does not have
a return type. :)

Trustin
-- 
what we call human nature in actually is human habit
--
http://gleamynode.net/

Re: [seda] event notifier pattern clarification

Posted by Trustin Lee <tr...@gmail.com>.
On Wed, 22 Sep 2004 02:00:28 -0700, Cetin Karakus
<ce...@gmail.com> wrote:
> Hi Alex,
> I think that  Advices are a kind of meta-filters with message
> transformation capabilities.
> In order for Advices to  transform EventObjects in interesting ways
> they need to access
> the context  provided by EventRouter. So, perhaps we need to introduce
> this into the Advice
> contract.

Attaching routing history on Event object would be nice.

By attaching the routing history on events we can:

* Know estimated process timer per each subscribers
* Route from routing history, for example, advice can route the event
corresponding to whether it has been visited the specific subscriber
or not.

This is just an idea and can be dangerous in the aspect of memory
usage of course.

Trustin
-- 
what we call human nature in actually is human habit
--
http://gleamynode.net/

Re: [seda] event notifier pattern clarification

Posted by Cetin Karakus <ce...@gmail.com>.
Hi Alex,
I think that  Advices are a kind of meta-filters with message
transformation capabilities.
In order for Advices to  transform EventObjects in interesting ways
they need to access
the context  provided by EventRouter. So, perhaps we need to introduce
this into the Advice
contract.





On Wed, 22 Sep 2004 01:35:02 -0400, Alex Karasulu <ao...@bellsouth.net> wrote:
> This is in reference to the Event Notifier pattern described here:
> 
> http://www.dralasoft.com/products/eventbroker/whitepaper/
> 
> Trustin, Enrique, Noel and I were discussing this on IRC.  Actually we
> were discussing how to handle situations were we need to change the way
> we route in complex ways sometimes based on:
> 
>  o event type (normal for pattern)
>  o event filters
>  o event properties/attributes
>  o extraneous logic
> 
> Any combination of the above can be used.  There were comments made
> about the weaknesses of this pattern specifically where EventType is
> used to determine how to route an event to Subscribers.  I agreed but
> soon realized that I'm very wrong and this email will tell you why.
> 
> The most important point to make is there are two dimensions to
> controlling routing in the standard pattern.
> 
> (i)  event type
> (ii) filters
> 
> The event type can totally be turned of by making subscribing for the
> root event type EventObject.  So one can subscribe Subscribers for all
> events and use logic within Filters to determine whether or not to
> inform() the Subscriber.  The logic in the filter can be as dynamic as
> you want it to be.  It can check EventObject properties or use
> extraneous parameters to determine if the Subscriber should be
> notified.  We can check the time of day, type of service event is
> associated with, and client specific information if that's what we want
> to use in making the routing decision.
> 
> So at the end of the day we have all the expressivity we need in this
> pattern which as stood the test of time.  However Trustin brought some
> interesting ideas to the table.  He spoke about transformations of
> Events before informing a Subscriber.  This got me thinking; this is
> another dimension for controling routing decisions.
> 
> I also had an idea of my own.  I thought about adding routing advice.
> Advice would prune, and/or augment the Subscribers consulted, it would
> also transform the event if necessary before delivering it to
> Subscribers.  This would extend the routing control of the pattern
> further than it has gone before (I think).  Perhaps this has already
> been done.
> 
> Here's how routing Advice could be administered to the router:
> 
> interface EventRouter {
> ...
>     apply(Advice);
> }
> 
> Here's how Advice would look:
> 
> interface Advice {
> ...
>     Subscription[] getSubscriptions(Event, Subscriptions[]);
>     Event getEvent(Event);
> }
> 
> Advice can be registered on the basis of event type too.  It does not
> hurt to do this at all if we just take the root of the event heirarchy
> then all events will be checked for advice.
> 
> Basically if there is advice for routing then the standard set of
> Subscriptions are ignored.  Only the ones returned by the Advice are
> used to inform.  Secondly the EventObject used to inform is transformed
> before the inform().  The EventObject may not have changed, it can just
> be returned as is if transformation via 'cloning' is not in effect.
> 
> WDYT?
> 
> Alex
> 
>