avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alex Karasulu <aok...@bellsouth.net>
Subject Re: Re: [RT] Notification pattern has interesting effects on IoC
Date Wed, 18 Feb 2004 16:26:48 GMT
You take a very thorough approach Leo.  I'm reading as an intent student
rather than a peer at this point.

> At a very high abstraction level, you might say that the 
> interface/service world is call-based ("composer calls method on 
> component" is what the avalon terms used to be). OTOH, publish/subscribe 
> and event systems are message-based ("sender sends message to 
> receiver"). 

This makes sense.  

> Let's take a look at these seperately and see if the emerging 
> technologies can work together.

Ahh thought experiments 


> Realizations in service-based design
> ------------------------------------
<snip/>
> In avalon, the decomposition choices have slowly evolved (exactly what 
> concerns we seperate into distinct "blocks" or "components" or 
> "facilities" or ...) from nearly non-specified (we stop at the concept 
> of ComponentManager) to nearly set-in-stone (we use a very rigid and 
> uniformly structured model as the basis of the merlin system). As long 
> as I've been at avalon, the trend has been towards more rigidity, 
> predicatibility, stability, etc. There have been a few attempts to 
> change that direction, but none of them ever gained the neccessary momentum.
> 
> Up to a few months ago, most people looking towards IoC were looking for 
> rigidity.
> 
> Realizations in message-based systems
> -------------------------------------
<snip/>

> In summary, message-based systems are difficult.
> 
> In avalon, we've tried marriage of the service paradigm with the message 
> paradigm a few times, at one point by introducing Commands and 
> Commandables into avalon-framework, at another point by defining 
> responsibilities of a message-based system (sender, receiver, queue, 
> ...) in excalibur-event. However, our resource identifiers (roles) have 
> always been particular, and never uniform. We did talk for a few weeks 
> about changing that, but never got round to it.
> 
> The most popular form of merging message-based systems with 
> service-based systems is probably found in some applications of the 
> servlet api, where HTTP messages are mapped to and from services. The 
> cleanest version of that is probably found in SOAP, and something like 
> Axis does a good job of mapping some core abstractions.

See much of drive for an message based approach came from a need to
get rid of cyclic dependencies and more importantly handle SEDA events.

> Message<->Service adapters
> --------------------------
> You can use tomcat+axis+a good bit of configuration and assembly to map 
> HTTP messages to services. You'll need to use a few registries and 
> discovery mechanisms before you can though (TCP/IP, DNS, WSDL, and more).
> 
> You can intersect a message layer between tomcat and your service engine 
> to translate between human-readable (HTML) and machine readable (the 
> method call, or often "action", which is a high-abstraction method 
> call). You'll need to use several registries as well here.

You're starting to get thick here man I think this is floating away
a bit but I follow.

<snip/>

> Now, we want, maybe, a "uniform" and "general" message<->service adapter.
> 
> This is, I think, just about what jicarilla-framework is about (though 
> I've only just realized that!). Let me try and explain.
> 
> The uniform message<->service adapter
> -------------------------------------
> At some point, you have some kind of message that you want some kind of 
> service to handle. Lets introduce an intermediary form. An Invocation. 
> Define services that can receive and handle invocations. Define 
> transformers that can convert between message formats and invocations. 
> Define how to create URNs for these transformers. Define mappings from 
> URIs to URNs. That's it.
> 
> I'm currently working on as generic and universal a message<->service 
> adapter as possible, which is at the same time also quite small. I'm 
> focussing on the web domain atm. It should (will) look like this...
> 
>     A client fires of a HTTP message. The web server handles the
>     low-level protocol. It sends the object representation of the message
>     to a broker/mapper. The broker handles the URI/URN translation, and
>     sends the message to a transformer found by URN. The transformer is
>     half of the bridge between the message-based system and the
>     service-based system. It creates an invocation and feeds it to the
>     service. The other half of the message<->service adapter lives in the
>     service itself or in some intermediary and transforms the conceptual
>     Invocation into an actual invocation.

that's cool - sounds complex to me

> Intermezzo
> ----------
> phew! That's a whole lot of typing, and I haven't really even talked 
> about notifications and dependencies. Lets try and get back down to 
> earth a little more.

ok

> Notification and callbacks
> --------------------------
> Not described above are callbacks/responses. Invocations create 
> responses, which need to be translated back to messages, and sent 
> somewhere. We might travel the whole "message bus" in reverse, or we 
> might go forward through a different bus. It's not that difficult to 
> figure out the former can be mapped to the latter, so in the quest for 
> "uniform" we'll pick the latter. Continuing my example
> 
>     The intermediary between the transformer and the service applies the
>     invocation to the service. The service returns a result from the
>     method call. The intermediary feeds this back to the transformer,
>     which translates the response to an object representation of an
>     HTTP message. This message is fed back to the web server, which
>     handles the low level protocol. The response arrives back at the
>     client.

Dude this is getting way more complex or the terminology is too thick.  
Perhaps at this point I'm just a casualty of the last section that took 
3 times to read before I understood it.  Perhaps I'm just slow.

> This is a request/response architecture, and its not general enough. It 
> seems we need an "event bus" or listener approach, where there can be 
> multiple publishers of the same message, and multiple recipients. we can 
> ath this point drift into the realm of JINI, JavaSpaces, and the like. 
> Since I don't fully understand most of that I won't go there.

Ok now I'm with u again.

> The point to take away
> ----------------------
> I think this is the big thing. The response to this:
> 
> > So the dependency graph turns into a star with all components depending on
> > the event router, hub, bus or whatever you call it in the center. Event
> > types and interfaces essentially become the dependency as opposed to the
> > service interfaces. This way you can introduce new subscribers and
> > publishers. Also the dynamic rerouting of events is possible at runtime.
> > What this means is that the dependencies between components can change on
> > the fly! Wow not a bad thang.
> 
> well, its less rigid. Have you gone through the introduction of lots of 
> rigidity by introducing a strict model for lots of things (declaring 
> loads of metadata and creating facilities to read/write/store it), only 
> to build a layer on top of it that takes all the rigidity away again?

So basically that's what this pattern does?  You had the rigidity with
the IoC stuff meta data and all that then the notification pattern/event bus
comes along and takes all the dependency based rigidity away?  Is that what 
you mean above?

> 
> > What does this mean for service interfaces? Well they start looking bleak
> > because the Subscriber interface replaces them. Basically methods are called
> > internally by the Subscriber handling code on the component itself rather
> > than exposing them on the service interface for direct calls by what are now
> > publishers. This is crazy my service interfaces are all empty now! 
> 
> I think you want to introduce a layer between your event-based system 
> that maps events to-and-from method calls. Your services don't change 
> (good thing), but you still get all the benefit of the event-based approach.

Why there are no method calls anymore?  The pattern uses a standard 
inform(EventObject) method for Subscribers.  Sure u can make this type
safe and specific by having a Subscriber heirarchy by haveing specialized
subinterfaces supporting signatures like inform(XYZEvent) or in on example
in Eve we have a ConnectSubscriber for ConnectEvents that has a type specific
inform(ConnectEvent).

> Otherwise, what's the benefit of using avalon at all?

Good question.  I have not answered that just yet.  But I'm thinking this
way.  Not every aspect of the system is best suited for pub/sub model.  The
IoC based dependency approach based on service interfaces is still valid.
You can mix these patterns to suit the need best.

Some things like SEDA servers are best modeled using a pub/sub model.  Or
systems with a high degree of interdependency can be decoupled nicely with
this pattern.  Some well formed systems may not and only get more complex 
with its introduction so its better to vear away from it.

Also a component can participate in the event bus as a subscriber and or 
a publisher.  But that does not necesarily mean that there will not be 
other orthogonal aspects to the service which are best modeled as service
interface methods.  You just can't call these operations using the pub/sub
model and hence there must be a service interface method for them.

The frontend to Eve is the perfect example of a system best suited for
the pub/sub model.  It's components are designed as stages based on events 
for the processing of requests.  So most of the service methods were 
designed around the processing of these stages.  When the event bus appeared
there was no need to expose these methods anymore since the component itself
was the only client to those methods.  It got an event and called its own 
method to process the event.  Take for example a decoder service.  Here's
what the service interface may look:

interface Decoder
{
   Message decode( byte[] buf ) ;
}


Now I introduce the InputEvent that means a message is comming into
the server.  The Decoder component implementing the Decoder interface 
subscribes as a listener for InputEvents with the event bus.   It 
gets the event and extracts the payload buffer:

inform( InputEvent a_event )
{
   byte[] l_buf = a_event.getBuffer() ;
   decode( l_buf ) ;
}

There is no need to expose decode anymore is there?  Perhaps you might
want to expose it for non-pipeline processing.  Meaning your not responding
to an event but just using the decode functionality.  So then you could 
leave it there.  See where i'm goin here?

Alex







---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org


Mime
View raw message