You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by Stephen McConnell <mc...@osm.net> on 2001/11/11 08:36:37 UTC

BlockListener and LifecycleHelper

After playing around with the Phoenix BlockListener I decided to transfer
our human interface centric block implementation to a block listener
instance.  The resulting code is much cleaner - however - I found some
limitations with the way LifecycleHelper handles listener instances.  Under
the CVS LifecycleHelper implementation the only component phase handled by
the helper is to configure the listener.  I want my listener to be log
enabled, contextualized, configured, and initalized.  So, I have updated
LifecycleHelper  to do exactly that by changing the startupListener method.
I though it would be worthwhile adding the updated version to the CVS
(source attached).

The diff for the source is included below.

Cheers, Steve.

-------------------------------------------------------------------------

RCS file:
/home/cvspublic/jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/co
mponents/application/LifecycleHelper.java,v
retrieving revision 1.18
diff -r1.18 LifecycleHelper.java
116c116,161
<         if( listener instanceof Configurable )
---
>         int stage = 0;
>
> 	  try
> 	  {
>             stage = STAGE_LOGGER;
>             if( listener instanceof Loggable )
>             {
>                 notice( name, stage );
>                 ((Loggable)listener).setLogger( m_context.getLogger(
name ) );
>             }
>             else if( listener instanceof LogEnabled )
>             {
>                 notice( name, stage );
>                 final Logger logger = new LogKitLogger(
m_context.getLogger( name ) );
>                 ((LogEnabled)listener).enableLogging( logger );
>             }
>
>             //Contextualize stage
>             stage = STAGE_CONTEXT;
>             if( listener instanceof Contextualizable )
>             {
>                 notice( name, stage );
>                 final BlockContext context = createBlockContext( name );
>                 ((Contextualizable)listener).contextualize( context );
>             }
>
>             stage = STAGE_CONFIG;
>             if( listener instanceof Configurable )
>             {
>                 notice( name, stage );
>                 final Configuration configuration = getConfiguration(
name, TYPE_LISTENER );
>                 ((Configurable)listener).configure( configuration );
>             }
>
>             //Initialize stage
>             stage = STAGE_INIT;
>             if( listener instanceof Initializable )
>             {
>                 notice( name, stage );
>                 ((Initializable)listener).initialize();
>             }
>
>             m_listenerSupport.addBlockListener( listener );
>
>         }
>         catch( final Throwable t )
118,119c163
<             final Configuration configuration = getConfiguration( name,
TYPE_LISTENER );
<             ((Configurable)listener).configure( configuration );
---
>             fail( name, stage, t );
122d165
<         m_listenerSupport.addBlockListener( listener );

Re: BlockListener and LifecycleHelper

Posted by Peter Donald <do...@apache.org>.
egads - was I having a bad spelling day when I sent this! ;)

On Sat, 17 Nov 2001 10:00, Peter Donald wrote:
> > You objected to this because you said that
> > listener logic should reside in a block.
>
> I said there was no such thing as listener logic. Listeners are just glue
> to stick together blocks appropriately ;)
>
> A while back I sent a lick to an article on javaworld. The articule
> basically discussed the separation between "procedural" and "declarative"
> parts of a system. Can't seem to find think at the moment ...

should be 

A while back I sent a link to an article on javaworld. The article
discussed the separation between "procedural" and "declarative" elements of a 
system. Can't seem to find the link at the moment ...

-- 
Cheers,

Pete

-----------------------------------------------
"Only two things are infinite, the universe and 
human stupidity, and I'm not sure about the 
former." -Albert Einstein 
-----------------------------------------------

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: BlockListener and LifecycleHelper

Posted by Peter Donald <do...@apache.org>.
On Sun, 18 Nov 2001 00:27, Stephen McConnell wrote:
> Peter Donald wrote:
> > On Sat, 17 Nov 2001 00:16, Stephen McConnell wrote:
> > > I want LifecycleHelper to invoke component lifecycle phases
> > > on a listener.
> >
> > right. I don't mind LogEnabled but I don't like any of the others ;)
> >
> > > You objected to this because you said that
> > > listener logic should reside in a block.
> >
> > I said there was no such thing as listener logic. Listeners are
> > just glue to stick together blocks appropriately ;)
>
> And I said that happended to by your use-case, not mine :-)

Right but the functionality you want to implement is already supported. My 
use-case was designed for application wide aspects / policy / facilities / 
whatever. So far you have yet to say where this model breaks down in your 
case. You just said it does. I need facts not opinions ;)

So what is missing from the model I propose that would;
* degrade quality of implementation/design
* make it impossible to implement some functionality
etc

The only thing I have considered is maybe that not enough events are 
supported. It may be useful to support other events such as

void applicationStarting() //before blocks are startedup
void applicationStarted() //when all blocks are started up
void applicationStopping() //before blocks are shutdown
void applicationStopped() //when all blocks are shutdown
void applicationFailure() //when application fails to load

It is possible that the above may be useful to add ... not sure aty this 
stage. (or at minimum the appStarted + appStopping)

> > coposition can't be done as there is no notion of dependencies.
> > initialization shouldn't really be done as no listener should be
> > allocating any significant resources (same reason for KB'ing
> > dispose)
>
> Agree - I should not have included compose (my mistake).  Let me
> outline the "component" interface that I want to see support
> for and the reasons why:
>
>    LogEnabled - If I'm logging anything within an object that's
>      declared as a listener, I don't want to have to set-up
>      another logger - just want to be supplied automagically

reasonable.

>    Contextualizable - this one is a little tricky - the code
>      I have is doing validation of the environment before blocks
>      kick in - validation needs the information about the
>      application context (available under the application meta-data
>      receivable under contextualization of a listener).

hmmm - is this a local modification? The only thing you can get from 
BlockContext as far as I see is the Application name and application dir. 
Have you modified it locally to get other stuff?

>  To veto
>      start-up, I need to be in application space (no block space)
>      because I can throw an exception and halt/suspend start-up.

Would adding notification of the events mentioned above work for this?

>    Initializable - Because I'm following Avalon component
>      pattern and this is the trigger to start working and I don't
>      like changing that without having some tangible
>      justification.

I need to know what "work" you are doing before I can judge whether it is 
something we want to support ;)

> > > I need to understand why your objecting to that.
> >
> > Put it this way. I see listeners as not doing any logic - they are
> > declarative constructs for establishing relationships. I want to know why
> > this will not work in your case.
>
> 1. because I am NOT wiring blocks together
> 2. because I don't have an alternative mechanism
> 3. because I object to assertion that the current listener declaration
>    is a valid "declarative constructs for establishing relationships"
>    (it only references a class name within the scope of the application
>    and declares nothing about relationships)
> 4. because I'm dealing with application policy
> 5. because I'm stubborn and you haven't given me a good tangible
>    technical argument why this is inappropriate
> 6. because I wanted to have a least six bullet points

;P

> > So far you have only indicated that you
> > "want" to do logic in listeners. I want to know why the listeners as
> > declaratives model doesn't work in your case or makes it harder
> > to construct your application. So far I haven't seen any indication that
> > this is so ;)
>
> I'm handling application level policy.  The registration of a listener
> is the only access point I have to plug-in an application-level facility.

right.

> This
> is a different use-case to yours - but that does not make it invalid - just
> different.  All I'm proposing is that IF a class, registered as a listener,
> exposes any of the above component interfaces, then, give the class what it
> needs to do its stuff correctly.

You still haven't really told me exactly what you want to do and why the 
current model doesn't work for you. If LogEnabled was supported and some 
extra events were added (like above) would you be able to implement what you 
want to implement?

-- 
Cheers,

Pete

*------------------------------------------------------*
| "Common sense is the collection of prejudices        |
|  acquired by age 18. " -Albert Einstein              |
*------------------------------------------------------*

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: BlockListener and LifecycleHelper

Posted by Stephen McConnell <mc...@osm.net>.
Peter Donald wrote:
> On Sat, 17 Nov 2001 00:16, Stephen McConnell wrote:
> > I want LifecycleHelper to invoke component lifecycle phases
> > on a listener.
>
> right. I don't mind LogEnabled but I don't like any of the others ;)
>
> > You objected to this because you said that
> > listener logic should reside in a block.
>
> I said there was no such thing as listener logic. Listeners are
> just glue to stick together blocks appropriately ;)

And I said that happended to by your use-case, not mine :-)

> A while back I sent a lick to an article on javaworld.

I bet that was a suprise for the Editor :-)

> The articule basically discussed the separation between
> "procedural" and "declarative" parts of a system. Can't seem
> to find think at the moment ...
>
> Blocks are definetly the procedural part of the system. They do things.
>
> I see listeners as the delacarative part. Essentially they manage
> rules such
> as
>
> * "All SOAPable Blocks are exported via a SOAPServer Block"
> * "All Blocks are managed by MyManager Block"
> * "All Persistable Blocks are persisted by MyPersistentManager Block"
> * "All RMIEnabled Blocks are exported by MyRMIExporter Block"
> * "All Repository Blocks are registered with all Store Blocks"
> * "All ... Blocks are ... by ... Block(s)"

What your decribing here is "one-potential-set-of-semantic" that a
listener may have.  That set of semantics is much more fine-grained
than the listener interface itself.  It is also a set of semantics
that has nothing to do with my application case.

> 1-to-1 listeners may also be viable and this is essentially the
> reason why I allow Configuration for Listeners.
>
> So Listeners still == Gaffer tape for Blocks ;)

For your use-case, not mine!

> > I objected to that
> > because I have "application" level logic that does not belong
> > in a block - it belongs in the listener. I think we both
> > agree that when logic is exposed to blocks, this done through
> > a block acting as a proxy to the listener.
>
> no - I definetly dont agree with that ;)

I'm not going to explore this one.

> Blocks provide the logic and may interact/provide services to
> other blocks.
> Listeners are only enablers of block interaction.
>
> > What we apparently
> > don't agree on is allowing a listener to be a component (i.e.
> > has a lifecycle covering contextualization, composition,
> > initialization, dispose, etc.
>
> coposition can't be done as there is no notion of dependencies.
> initialization shouldn't really be done as no listener should be
> allocating any significant resources (same reason for KB'ing
> dispose)

Agree - I should not have included compose (my mistake).  Let me
outline the "component" interface that I want to see support
for and the reasons why:

   LogEnabled - If I'm logging anything within an object that's
     declared as a listener, I don't want to have to set-up
     another logger - just want to be supplied automagically

   Contextualizable - this one is a little tricky - the code
     I have is doing validation of the environment before blocks
     kick in - validation needs the information about the
     application context (available under the application meta-data
     receivable under contextualization of a listener).  To veto
     start-up, I need to be in application space (no block space)
     because I can throw an exception and halt/suspend start-up.
     There are alternative such as extending the embeddor but this
     means creating a different Phoenix which I want to avoid.

   Configurable - I'm holding my application policy here.

   Initializable - Because I'm following Avalon component
     pattern and this is the trigger to start working and I don't
     like changing that without having some tangible
     justification.

   Disposable - arguments are the same as initalize.

> > I need to understand why your objecting to that.
>
> Put it this way. I see listeners as not doing any logic - they are
> declarative constructs for establishing relationships. I want to know why
> this will not work in your case.

1. because I am NOT wiring blocks together
2. because I don't have an alternative mechanism
3. because I object to assertion that the current listener declaration
   is a valid "declarative constructs for establishing relationships"
   (it only references a class name within the scope of the application
   and declares nothing about relationships)
4. because I'm dealing with application policy
5. because I'm stubborn and you haven't given me a good tangible
   technical argument why this is inappropriate
6. because I wanted to have a least six bullet points

> So far you have only indicated that you
> "want" to do logic in listeners. I want to know why the listeners as
> declaratives model doesn't work in your case or makes it harder
> to construct your application. So far I haven't seen any indication that
> this is so ;)

I'm handling application level policy.  The registration of a listener
is the only access point I have to plug-in an application-level facility.
This
is a different use-case to yours - but that does not make it invalid - just
different.  All I'm proposing is that IF a class, registered as a listener,
exposes any of the above component interfaces, then, give the class what it
needs to do its stuff correctly.

Cheers, Steve.


> --
> Cheers,
>
> Pete
>
> ---------------------------------------------------------
> Clarke's Third Law: "Any technology distinguishable from
> magic is insufficiently advanced".
> ---------------------------------------------------------
>
> --
> To unsubscribe, e-mail:
> <ma...@jakarta.apache.org>
> For additional commands, e-mail:
> <ma...@jakarta.apache.org>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: BlockListener and LifecycleHelper

Posted by Peter Donald <do...@apache.org>.
On Sat, 17 Nov 2001 00:16, Stephen McConnell wrote:
> I want LifecycleHelper to invoke component lifecycle phases
> on a listener. 

right. I don't mind LogEnabled but I don't like any of the others ;)

> You objected to this because you said that
> listener logic should reside in a block. 

I said there was no such thing as listener logic. Listeners are just glue to 
stick together blocks appropriately ;)

A while back I sent a lick to an article on javaworld. The articule basically 
discussed the separation between "procedural" and "declarative" parts of a 
system. Can't seem to find think at the moment ...

Blocks are definetly the procedural part of the system. They do things.

I see listeners as the delacarative part. Essentially they manage rules such 
as 

* "All SOAPable Blocks are exported via a SOAPServer Block"
* "All Blocks are managed by MyManager Block"
* "All Persistable Blocks are persisted by MyPersistentManager Block"
* "All RMIEnabled Blocks are exported by MyRMIExporter Block"
* "All Repository Blocks are registered with all Store Blocks"
* "All ... Blocks are ... by ... Block(s)"

1-to-1 listeners may also be viable and this is essentially the reason why I 
allow Configuration for Listeners.

So Listeners still == Gaffer tape for Blocks ;)

> I objected to that
> because I have "application" level logic that does not belong
> in a block - it belongs in the listener. I think we both
> agree that when logic is exposed to blocks, this done through
> a block acting as a proxy to the listener.  

no - I definetly dont agree with that ;)

Blocks provide the logic and may interact/provide services to other blocks. 
Listeners are only enablers of block interaction.


> What we apparently
> don't agree on is allowing a listener to be a component (i.e.
> has a lifecycle covering contextualization, composition,
> initialization, dispose, etc. 

coposition can't be done as there is no notion of dependencies. 
initialization shouldn't really be done as no listener should be allocating 
any significant resources (same reason for KB'ing dispose)

contextualization I just don't see a need for. There is no acceptable usecase 
I can think of but I am sure if one was found I may change my mind.

> I need to understand why your objecting to that.

Put it this way. I see listeners as not doing any logic - they are 
declarative constructs for establishing relationships. I want to know why 
this will not work in your case. So far you have only indicated that you 
"want" to do logic in listeners. I want to know why the listeners as 
declaratives model doesn't work in your case or makes it harder to construct 
your application. So far I haven't seen any indication that this is so ;)

-- 
Cheers,

Pete

---------------------------------------------------------
Clarke's Third Law: "Any technology distinguishable from 
magic is insufficiently advanced".
---------------------------------------------------------

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: BlockListener and LifecycleHelper

Posted by Stephen McConnell <mc...@osm.net>.
Pete:

I want LifecycleHelper to invoke component lifecycle phases
on a listener.  You objected to this because you said that
listener logic should reside in a block.  I objected to that
because I have "application" level logic that does not belong
in a block - it belongs in the listener.  I think we both
agree that when logic is exposed to blocks, this done through
a block acting as a proxy to the listener.  What we apparently
don't agree on is allowing a listener to be a component (i.e.
has a lifecycle covering contextualization, composition,
initialization, dispose, etc.  I need to understand why your
objecting to that.

Cheers, Steve.


> -----Original Message-----
> From: Peter Donald [mailto:donaldp@apache.org]
> Sent: Friday, 16 November, 2001 13:50
> To: Avalon Developers List
> Subject: Re: BlockListener and LifecycleHelper
>
>
> Hi,
>
> On Wed, 14 Nov 2001 05:44, Stephen McConnell wrote:
> > > > > So it should not under any circumstances have any real logic
> > > > > included in it.
> > > >
> > > > BlockListener provides a clean mechanism for extension of
> > > > Phoenix.
> > >
> > > agreed. BlockListeners were intended to provide all those
> > > features that are not general enough to be kernel services -
> > > like BlockPersistence, exporting via RMI/SOAP/Other,
> > > exporting via a Management system or whatever.
> > >
> > > > While this may not have been the intent - (a) such a
> > > > mechanism is needed, and (b) the "no real logic" principal your
> > > > noted seems to be relevant to the use case you had in mind (i.e.
> > > > handling inter-working of blocks).
> > >
> > > still think it is ;)
> >
> > Given an implementation that is not intended to be a service to
> > a block (or should not be exposed to blocks), I cannot see why a
> > listener should not be treated as a component.  I'm guessing that
> > your concern is that listeners will be created that declare
> > themselves as services - which I think is an inappropriate
> > use of the interface. I'm also guessing that your concerned about
> > the duplication effect created under the current implementation when
> > a listener is also a block.  In particular:
> >
> >   1. listener only
> >      - no issue
> >   2. listener implementing the component interfaces
> >      - if listener does not implement block, then there
> >        are no obvious reasons (an none declared this list
> >        so far :-)) for the listener not handled in a
> >        component lifecycle sequence
> >   3. listener implementing the Block interface
>
> not viable as listeners need to be created before blocks (Or else
> they will
> miss out on events). It would be logical impossibility for
> something to be
> created before it is created ;)
>
> > > Right. But the question is - could it be a Block? I mean - what
> > > would be the negative side of making it a Block and having other
> > > Blocks "registered" with management system. The registration (and
> > > unregistration) would be done via the BlockListener. Making this
> > > .sar wide service a Block has the advantage that other Blocks may
> > > choose to depend on it.
> >
> > This approach blurs the issue of the object lifecycle of a listener
> > with the object lifecycle of a block.  I don't think a listener should
> > be allowed to be a block because they are orthogonal to each other.
>
> agreed.
>
> > A
> > listeners lifecycle is linked to the sar file and as such exists for
> > the lifetime of the application.  A block's lifecycle is a transient
> > sub-set of the application's lifecycle.
>
> right.
>
> > However, a block could be provided that handles the establishment
> > of a relationship with a listener, and that block could then provide
> > support to the listener and other blocks. This scenario is ok because
> > we are clearly separating the implementations that deal with different
> > phases of execution (application versus phoenix).  The ideal scenario
> > would be the formal specification of a "Facility" (a object
> > that implements Component and BlockListener).
>
> I am not sure exactly what you are saying here. In my mind
>
> Facility = Listener + Block
> * Listener to map blocks who request facility to the block that provides
> facility
> * Block to actually implement Facility
>
> All logic is still in the Block as far as I can see.
>
> > > You should ALWAYS explicitly enforce your contracts.  This leads to
> > > secure components that cannot be interacted with in ways you had no
> > > intention of allowing.
> > >
> > :-)
>
> And I think I may have stated that this is not what I do or even
> recomend ;)
>
> I think it is a responsibility of the container to maintain correct
> propogation of lifecycle events. No other untrusted object should
> ever get a
> direct reference to the object and thus no other object should be able to
> call the lifecycle events. This is almost true in Avalon/Phoenix
> and will be
> fully true in the future (currently a Block can pass a reference
> of itself to
> another Block and that reference is not protected).
>
> In cases where you may not have a proper secure environment or no clear
> separation between container and componentss then such defensive
> programming
> may become applicable but I don't think it is applicable in Phoenix ;)
>
> > Conclusion - an object should not implement BlockListener and Block.
>
> agreed.
>
> > If
> > a developer wants to provide services to other blocks, he/she should
> > provide a proxy-block (where the listener establishes a
> contract with the
> > proxy-block
> > which in turn exposes application level services to dependent blocks).
>
> exactly. So wasn't that I was saying with my BlockListener
> example ... hmmm
> now I am confused ... I think ;)
>
> So are we agreeing or not ? ;)
>
> --
> Cheers,
>
> Pete
>
> -----------------------------------------------------------
>  Don't take life too seriously --
>                           you'll never get out of it alive.
> -----------------------------------------------------------
>
> --
> To unsubscribe, e-mail:
<ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: BlockListener and LifecycleHelper

Posted by Peter Donald <do...@apache.org>.
Hi,

On Wed, 14 Nov 2001 05:44, Stephen McConnell wrote:
> > > > So it should not under any circumstances have any real logic
> > > > included in it.
> > >
> > > BlockListener provides a clean mechanism for extension of
> > > Phoenix.
> >
> > agreed. BlockListeners were intended to provide all those
> > features that are not general enough to be kernel services -
> > like BlockPersistence, exporting via RMI/SOAP/Other,
> > exporting via a Management system or whatever.
> >
> > > While this may not have been the intent - (a) such a
> > > mechanism is needed, and (b) the "no real logic" principal your
> > > noted seems to be relevant to the use case you had in mind (i.e.
> > > handling inter-working of blocks).
> >
> > still think it is ;)
>
> Given an implementation that is not intended to be a service to
> a block (or should not be exposed to blocks), I cannot see why a
> listener should not be treated as a component.  I'm guessing that
> your concern is that listeners will be created that declare
> themselves as services - which I think is an inappropriate
> use of the interface. I'm also guessing that your concerned about
> the duplication effect created under the current implementation when
> a listener is also a block.  In particular:
>
>   1. listener only
>      - no issue
>   2. listener implementing the component interfaces
>      - if listener does not implement block, then there
>        are no obvious reasons (an none declared this list
>        so far :-)) for the listener not handled in a
>        component lifecycle sequence
>   3. listener implementing the Block interface

not viable as listeners need to be created before blocks (Or else they will 
miss out on events). It would be logical impossibility for something to be 
created before it is created ;)

> > Right. But the question is - could it be a Block? I mean - what
> > would be the negative side of making it a Block and having other
> > Blocks "registered" with management system. The registration (and
> > unregistration) would be done via the BlockListener. Making this
> > .sar wide service a Block has the advantage that other Blocks may
> > choose to depend on it.
>
> This approach blurs the issue of the object lifecycle of a listener
> with the object lifecycle of a block.  I don't think a listener should
> be allowed to be a block because they are orthogonal to each other. 

agreed.

> A
> listeners lifecycle is linked to the sar file and as such exists for
> the lifetime of the application.  A block's lifecycle is a transient
> sub-set of the application's lifecycle.

right.

> However, a block could be provided that handles the establishment
> of a relationship with a listener, and that block could then provide
> support to the listener and other blocks. This scenario is ok because
> we are clearly separating the implementations that deal with different
> phases of execution (application versus phoenix).  The ideal scenario
> would be the formal specification of a "Facility" (a object
> that implements Component and BlockListener).

I am not sure exactly what you are saying here. In my mind 

Facility = Listener + Block 
* Listener to map blocks who request facility to the block that provides 
facility
* Block to actually implement Facility

All logic is still in the Block as far as I can see.

> > You should ALWAYS explicitly enforce your contracts.  This leads to
> > secure components that cannot be interacted with in ways you had no
> > intention of allowing.
> >
> :-)

And I think I may have stated that this is not what I do or even recomend ;)

I think it is a responsibility of the container to maintain correct 
propogation of lifecycle events. No other untrusted object should ever get a 
direct reference to the object and thus no other object should be able to 
call the lifecycle events. This is almost true in Avalon/Phoenix and will be 
fully true in the future (currently a Block can pass a reference of itself to 
another Block and that reference is not protected).

In cases where you may not have a proper secure environment or no clear 
separation between container and componentss then such defensive programming 
may become applicable but I don't think it is applicable in Phoenix ;)

> Conclusion - an object should not implement BlockListener and Block. 

agreed.

> If
> a developer wants to provide services to other blocks, he/she should
> provide a proxy-block (where the listener establishes a contract with the
> proxy-block
> which in turn exposes application level services to dependent blocks).

exactly. So wasn't that I was saying with my BlockListener example ... hmmm 
now I am confused ... I think ;)

So are we agreeing or not ? ;)

-- 
Cheers,

Pete

-----------------------------------------------------------
 Don't take life too seriously -- 
                          you'll never get out of it alive.
-----------------------------------------------------------

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: BlockListener and LifecycleHelper

Posted by Stephen McConnell <mc...@osm.net>.
Pete:

See notes in-line :-)

Steve.

> -----Original Message-----
> From: Peter Donald [mailto:donaldp@apache.org]
> Sent: Tuesday, 13 November, 2001 11:34
> To: Avalon Developers List
> Subject: Re: BlockListener and LifecycleHelper
>
>
> On Tue, 13 Nov 2001 04:52, Stephen McConnell wrote:
> > > > After playing around with the Phoenix BlockListener I decided
> > > > to transfer our human interface centric block implementation
> > > > to a block listener instance.  The resulting code is much
> > > > cleaner - however - I found some limitations with the way
> > > > LifecycleHelper handles listener instances.  Under the CVS
> > > > LifecycleHelper implementation the only component phase
> > > > handled by the helper is to configure the listener.  I want
> > > > my listener to be log enabled, contextualized, configured,
> > > > and initalized.  So, I have updated LifecycleHelper to do
> > > > exactly that by changing the startupListener method.
> > > > I though it would be worthwhile adding the updated version
> > > > to the CVS (source attached).
> > >
> > > Im not sure you are using the BlockListener in the way that I
> > > intended it to be used ;) Basically the purpose of a
> > > BlockListener in my mind is to act as an enabler for
> > > relationships between blocks (besides a dependency
> > > relationship).
> >
> > I'm looking at BlockListener as open mechanisms (open in the sence
> > that it declared in assembly.xml) though which I can plug a component
> > that monitors the starting up and shutting down of any block
> > installed in a particular sar.
>
> right.
>
> > > So it should not under any circumstances have any real logic
> > > included in it.
> >
> > BlockListener provides a clean mechanism for extension of
> > Phoenix.
>
> agreed. BlockListeners were intended to provide all those
> features that are not general enough to be kernel services -
> like BlockPersistence, exporting via RMI/SOAP/Other,
> exporting via a Management system or whatever.
>
> > While this may not have been the intent - (a) such a
> > mechanism is needed, and (b) the "no real logic" principal your
> > noted seems to be relevant to the use case you had in mind (i.e.
> > handling inter-working of blocks).
>
> still think it is ;)

Given an implementation that is not intended to be a service to
a block (or should not be exposed to blocks), I cannot see why a
listener should not be treated as a component.  I'm guessing that
your concern is that listeners will be created that declare
themselves as services - which I think is an inappropriate
use of the interface. I'm also guessing that your concerned about
the duplication effect created under the current implementation when
a listener is also a block.  In particular:

  1. listener only
     - no issue
  2. listener implementing the component interfaces
     - if listener does not implement block, then there
       are no obvious reasons (an none declared this list
       so far :-)) for the listener not handled in a
       component lifecycle sequence
  3. listener implementing the Block interface
     - there is a potential for conflicting execution logic
       if the same component can be subject to multiple
       lifecycle actions - this is close to what is currently
       implemented except that the configure method could be
       invoked twice (which can be handled by the
       implementation by getting the configuration name - but
       it's not a nice approach).
     - the appears to be issue concerning phasing between
       the listener's reception of events, and its readiness
       to handle these events because the block may not have
       been contextualized/configured/initalized, etc.  I.e.
       we are forcing a requirement on a combined block/listener
       to handle events independently of its execution state


> > > The Blocks should contain the logic. The Listener is just there
> > > to link the "client" blocks with the "server" block.
> >
> > In my case, the functions I am implementing under the listener is
> > not a block - it is a component that extends the functionality
> > of the Phoenix platform.
>
> Right. But the question is - could it be a Block? I mean - what
> would be the negative side of making it a Block and having other
> Blocks "registered" with management system. The registration (and
> unregistration) would be done via the BlockListener. Making this
> .sar wide service a Block has the advantage that other Blocks may
> choose to depend on it.

This approach blurs the issue of the object lifecycle of a listener
with the object lifecycle of a block.  I don't think a listener should
be allowed to be a block because they are orthogonal to each other.  A
listeners lifecycle is linked to the sar file and as such exists for
the lifetime of the application.  A block's lifecycle is a transient
sub-set of the application's lifecycle.

However, a block could be provided that handles the establishment
of a relationship with a listener, and that block could then provide
support to the listener and other blocks. This scenario is ok because
we are clearly separating the implementations that deal with different
phases of execution (application versus phoenix).  The ideal scenario
would be the formal specification of a "Facility" (a object
that implements Component and BlockListener).

> If the only differences between BlockListener and Block are;
> * listeners get events about other blocks
> * blocks can have dependency relationships
>
> then I don't see an advantage of making a distinction between the two.

All of the OSM block enforce the Avalon Component design patterns. Our
blocks will throw exceptions if attempts are made to use them outside
of the Component usage model.  Keep in mind that this isn't just
following a pattern - things like block initialisation establish
distributed service context (including principal identities, etc.).
By mixing in BlockListener we are introducing a "special case".

Berin Loritsch wrote (a couple of minutes ago)
> You should ALWAYS explicitly enforce your contracts.  This leads to
> secure components that cannot be interacted with in ways you had no
> intention of allowing.

:-)

Conclusion - an object should not implement BlockListener and Block. If
a developer wants to provide services to other blocks, he/she should provide
a proxy-block (where the listener establishes a contract with the
proxy-block
which in turn exposes application level services to dependent blocks).

Cheers, Steve.

Stephen J. McConnell, OSM sarl
digital products for a global economy
http://www.osm.net
mailto:mcconnell@osm.net



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: BlockListener and LifecycleHelper

Posted by Peter Donald <do...@apache.org>.
On Tue, 13 Nov 2001 04:52, Stephen McConnell wrote:
> > > After playing around with the Phoenix BlockListener I decided
> > > to transfer our human interface centric block implementation
> > > to a block listener instance.  The resulting code is much
> > > cleaner - however - I found some limitations with the way
> > > LifecycleHelper handles listener instances.  Under the CVS
> > > LifecycleHelper implementation the only component phase
> > > handled by the helper is to configure the listener.  I want
> > > my listener to be log enabled, contextualized, configured,
> > > and initalized.  So, I have updated LifecycleHelper to do
> > > exactly that by changing the startupListener method.
> > > I though it would be worthwhile adding the updated version
> > > to the CVS (source attached).
> >
> > Im not sure you are using the BlockListener in the way that I
> > intended it to be used ;) Basically the purpose of a
> > BlockListener in my mind is to act as an enabler for
> > relationships between blocks (besides a dependency
> > relationship).
>
> I'm looking at BlockListener as open mechanisms (open in the sence
> that it declared in assembly.xml) though which I can plug a component
> that monitors the starting up and shutting down of any block
> installed in a particular sar.

right.

> > So it should not under any circumstances have any real logic
> > included in it.
>
> BlockListener provides a clean mechanism for extension of
> Phoenix. 

agreed. BlockListeners were intended to provide all those features that are 
not general enough to be kernel services - like BlockPersistence, exporting 
via RMI/SOAP/Other, exporting via a Management system or whatever.

> While this may not have been the intent - (a) such a
> mechanism is needed, and (b) the "no real logic" principal your
> noted seems to be relevant to the use case you had in mind (i.e.
> handling inter-working of blocks).

still think it is ;)

> > The Blocks should contain the logic. The Listener is just there
> > to link the "client" blocks with the "server" block.
>
> In my case, the functions I am implementing under the listener is
> not a block - it is a component that extends the functionality
> of the Phoenix platform.

Right. But the question is - could it be a Block? I mean - what would be the 
negative side of making it a Block and having other Blocks "registered" with 
management system. The registration (and unregistration) would be done via 
the BlockListener. Making this .sar wide service a Block has the advantage 
that other Blocks may choose to depend on it. 

If the only differences between BlockListener and Block are;
* listeners get events about other blocks
* blocks can have dependency relationships

then I don't see an advantage of making a distinction between the two. 


-- 
Cheers,

Pete

"Artists can color the sky red because they know it's blue.  Those of us who
 aren't artists must color things the way they really are or people might 
 think we're stupid." -- Jules Feiffer 

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: BlockListener and LifecycleHelper

Posted by Stephen McConnell <mc...@osm.net>.

Peter Donald wrote:
> Sent: Monday, 12 November, 2001 08:02
> To: Avalon Developers List
> Subject: Re: BlockListener and LifecycleHelper
>
>
> Hi,
>
> On Sun, 11 Nov 2001 18:36, Stephen McConnell wrote:
> > After playing around with the Phoenix BlockListener I decided
> > to transfer our human interface centric block implementation
> > to a block listener instance.  The resulting code is much
> > cleaner - however - I found some limitations with the way
> > LifecycleHelper handles listener instances.  Under the CVS
> > LifecycleHelper implementation the only component phase
> > handled by the helper is to configure the listener.  I want
> > my listener to be log enabled, contextualized, configured,
> > and initalized.  So, I have updated LifecycleHelper to do
> > exactly that by changing the startupListener method.
> > I though it would be worthwhile adding the updated version
> > to the CVS (source attached).
>
> Im not sure you are using the BlockListener in the way that I
> intended it to be used ;) Basically the purpose of a
> BlockListener in my mind is to act as an enabler for
> relationships between blocks (besides a dependency
> relationship).

I'm looking at BlockListener as open mechanisms (open in the sence
that it declared in assembly.xml) though which I can plug a component
that monitors the starting up and shutting down of any block
installed in a particular sar.

> So it should not under any circumstances have any real logic
> included in it.

BlockListener provides a clean mechanism for extension of
Phoenix. While this may not have been the intent - (a) such a
mechanism is needed, and (b) the "no real logic" principal your
noted seems to be relevant to the use case you had in mind (i.e.
handling inter-working of blocks).

> The Blocks should contain the logic. The Listener is just there
> to link the "client" blocks with the "server" block.

In my case, the functions I am implementing under the listener is
not a block - it is a component that extends the functionality
of the Phoenix platform.

> I just updated the documentation to include a blurb about block
> listeners (see what-is-a-block-listener.xml). See if that makes
> it clearer and if you agree.

The definition in what-is-a-block-listener.xml describes a scenario
where a particular "block" is using the information about available
blocks within an application instance as the principal arguments.
In that example, the notion of "no real logic" makes sence.  However,
my scenario (an extension to Phoenix application management) also
meets the description in the BlockListener is a "component" (and
according to the Avalon "what-is-a-component.xml", a component has
a managed lifecycle which is exactly the point that I'm addressing.

> I am still not sure about the wisdom of allowing listeners to be
> configured but I really don't think listeners should be contextualized or
> initialized.

If you think about the listener as an extension to the Phoenix/sar
context, the listener should be treated as a component (i.e. a component
that can have a logger assigned, can receive context, can be configured
and initalized. I think this comes down to the question of handling
Phoenix extension - how can Phoenix functionality be extended in a way
that is orthogonal to the question of blocks.

Cheers, Steve.



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: BlockListener and LifecycleHelper

Posted by Peter Donald <do...@apache.org>.
Hi,

On Sun, 11 Nov 2001 18:36, Stephen McConnell wrote:
> After playing around with the Phoenix BlockListener I decided to transfer
> our human interface centric block implementation to a block listener
> instance.  The resulting code is much cleaner - however - I found some
> limitations with the way LifecycleHelper handles listener instances.  Under
> the CVS LifecycleHelper implementation the only component phase handled by
> the helper is to configure the listener.  I want my listener to be log
> enabled, contextualized, configured, and initalized.  So, I have updated
> LifecycleHelper  to do exactly that by changing the startupListener method.
> I though it would be worthwhile adding the updated version to the CVS
> (source attached).

Im not sure you are using the BlockListener in the way that I intended it to 
be used ;) Basically the purpose of a BlockListener in my mind is to act as 
an enabler for relationships between blocks (besides a dependency 
relationship).

So it should not under any circumstances have any real logic included in it. 
The Blocks should contain the logic. The Listener is just there to link the 
"client" blocks with the "server" block.

I just updated the documentation to include a blurb about block listeners 
(see what-is-a-block-listener.xml). See if that makes it clearer and if you 
agree.


I am still not sure about the wisdom of allowing listeners to be configured 
but I really don't think listeners should be contextualized or initialized. 
LogEnabled may be an option though .. not sure.

thoughts?

-- 
Cheers,

Pete

---------------------------------------------------------------
The difference between genius, and stupidity? Genius has limits
---------------------------------------------------------------

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>