You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Berin Loritsch <bl...@apache.org> on 2002/06/06 16:55:44 UTC

[Design] ContainerManager is under fire--let's find the best resolution

If anyone is subscribed to the JAMES list, please include them on the
conversation.  This is an important issue that requires the attention
of everyone involved.  The next generation of the ComponentManager will
be simplified from the current implementation, which will force some
projects to change the way they design their systems and interfaces.

Therefore, I suggest we come together on how we lookup and use our
components.  Currently there are three trains of thought: one inspired
by the ECM (monolithic), one inspired by Phoenix(only lookup), and one
inspired by Fortress(in the middle).

The first order of business is that we need to be clear on our
terminology.

* Component -- a managed resource that is resolved at runtime (late
binding)
* Container -- a resource manager that resolves component instances
* Lookup Mechanism -- the interface that the client uses to lookup
components
* Client -- the code that uses components

I would love to give an illustration, but its copyrighted...

Anyway, here we go:

MONOLITHIC DESIGN
-----------------
No other way to say it than its bad.  By merging all the concerns into
one
entity, we are tempted to do to add new methods to the lookup mechanism.
One example that was probably (in retrospect) ill advised was the
"release()"
method on the CM.  At the time both Giacomo and I argued that the only
way
a container would have the knowledge that a client is done with a
component
is to explicitly say so.  Having seen what has happened in Cocoon's
explosion
of component types and interfaces, I can see there are better ways of
doing
things.  The section at the end will identify exactly what I mean.

SEPARATED CONCERNS
------------------
We have all been indoctrinated at how good this is.  We know because we
use it.
Avalon components are much less painful to develop than EJBs, and a
large part
of that is because EJB design uses a monolithic mindset and Avalon uses
SOC.
A container is a container.  A lookup mechanism is a lookup mechanism.
There
is nothing more that needs to be said about that other than what is
philisophically
separate should be separate in code.

SOMEWHERE IN THE MIDDLE
-----------------------
I started on Fortress with the mindset of correcting the most heinous
wrongs
committed by the ECM.  A Container is a Container, and a lookup
mechanism is
a lookup mechanism.  However, in an attempt to maintain as much
compatibility
with the ECM as possible it inherited a couple of the shortcommings.
However,
correcting those wrongs would require changing the way we write
components.

The origional ComponentManager Interface
----------------------------------------

interface ComponentManager
{
    Component lookup( String role ) throws ComponentException;
}

That was it.  Nothing more.  The whole problem started with the need for
named
components, or components resolved by a hint.  As a ressult we invented
the
ComponentSelector (actually in Cocoon there was a
"NamedCOmponentManager" that
resolved "NamedComponents").  The Avalon team did correctly deduce that
there
was no real need for NamedComponents.  The name, or hint is a function
that
the container assigns to a component--not something inherent in the
component
itself.

Then cocoon needed a mechanism for pooled components.  However there was
no
way to return a component instance to the container.  Peter tried to
tell us
that it can be done, and that it should not be done at the CM level.  In
retrospect, I am sorry we prevailed.  As a result, we have the
following:

interface ComponentManager
{
    Component lookup( String role ) throws ComponentException;
    boolean hasComponent( String role );
    void release( Component comp );
}

and

interface ComponentSelector
{
    Component lookup( Object hint ) throws ComponentException;
    boolean hasComponent( Object hint );
    void release();
}

                             -o0o-

In an attempt to remove the ComponentSelector abstraction,  I came up
with
something that would be a high performance CM interface.  It used a
Request
or Prototype object to resolve the request for a component ahead of
time.
As a result, we could safely remove the requirement for the
ComponentException.
At first I thought it would be a step forward, and I pitched it to the
Avalon list.  When I got some opposition from Peter and Leo, I pitched
it to
Stefano to see if he could recommend anything.

Surprisingly enough, Stefano's reply was simply

"Ok, just one (maybe stupid) question: what's wrong in something like
this:

interface ComponentManager {
     Component getComponent(String role);
     Component getComponent(String role, Object hint);
     ...
}
"

with a further clarification of

"I currently disklike the abuse of (non-runtime) exceptions that Avalon
throw
to indicate things that are not found. A try/catch requires the JVM to
save
the state of the execution (sort-of an internal
continuation) and this is a very expensive process.

"The code above is much more performant and friendly in that respect,
even if
I still don't understand the need for those 'request' stubs."

Which raises two very good points.  How should we handle the CM
interface,
and do we need exceptions?

As a result, I would like to go back to grass roots, with a couple
modifications.

Here is the interface for the CM:

interface ComponentManager
{
    Object lookup(String role);
    Object lookup(String role, Object hint);
    boolean exists(String role);
    boolean exists(String role, Object hint);
}

If you notice, there are four distinct differences from the current
ComponentManger:

1) We return Object instead of Component.  This merges the lessons
learned from
   the ServiceManager discussions about accessing legacy components that
are not
   able to emplement the Component interface.

2) We remove all *declared* exceptions.  If there is something wrong, it
is more
   appropriate to throw a RuntimeException.

3) We add an additional lookup and hasComponent method (role, hint
combination).

4) We remove the release() method altogether.


Now, I forsee few raised flags with the first three changes.  They
simplify our
lives, and help make truly performant code.  The role/hint combo takes
its cue
from a common construct in Java, used in JSSE, i18n resolution, and many
other
factories.  Basically there is a default implementation, and the hint is
used
to let the "factory" choose a different implementation than the default
if need
be.  It also lets us get rid of the ComponentSelector.

In this case, it is a hint to the Container that I not only want a
ConnectionManger,
I want one that handles TLS connections.  That way, we can look it up in
one call,
with no string concatenations:

ConnectionManager conn =
   (ConnectionManager) manager.lookup( ConnectionManager.ROLE, "TLS" );

There is little confustion, and if the hint is not supplied, the CM
returns the
default implemenatation.  It also lets us resolve bundles using a
Locale:

XMLBundle bundle = (XMLBundle) manager.lookup( XMLBundle.ROLE,
Locale.getInstance("US") );

Or something like that...

What will require some convincing--esp. to the Cocoon crew is the
removal of
the release() method.  To that end, read the last section.


                   -o0  What needs to change 0o-

In order for a container to manage component instances using pools or
per/lookup
policies, we need to change the way we think about our components.
Consider the
DataSourceComponent as a prototype.  With the DataSourceComponent, the
client
code does not care how the Connection object came into existance.  It
does not
care that it has been used 100 times before.  All it cares about is that
the
Connection is ready to be used now.  The DataSourceComponent does not
have a
release method, but yet it manages to pool the Connection instances.

The secret is the proxy layer.  The proxy layer is a wrapper around the
Connection
object, that intercepts calls to the Connection's "close" method.  As a
result
instead of truly closing the connection, it merely returns the
Connection to
the pool.  The proxy also adds a method to check if the connection is
still alive.

So the proxy is one way of ensuring we have a component.  It is also a
way of
returning a component automatically after a certain timeout has elapsed.
If the
component is needed again, the proxy is able to pull a new instance from
the
pool to perform the task.  However, such a use does have consequences to
the design
of your components (i.e. a component can't store state information if it
would
automatically be returned to a pool after a timeout).

One of the nice things about a proxy style component is that we can also
enable
a type of garbage collection behind the scenes.  Consider Cocoon.
Cocoon has
a hierarchy with the Cocoon object as the root container, and each
sitemap is
a container in and of itself.  Each container in the hierarchy knows
when a
request has been fulfilled--one way or another.  As a result, the
container can
clean up all the components automatically without consulting the child
components
if they are done with the handles yet or not.

Cocoon's pipeline components like the generators, serializers, et. al.
would either
need to be designed so that they are automatically returned to the
container
when they are done being used, or they would need to be changed so that
the Generator
returns an XMLSource, the Serializer returns a ContentHandler, and the
Transformer
returns an object that mixes the two.  Once the pipeline has hit the
endDocument()
SAX event, it can clean up after itself!

In order to make it easier for the component developers, we need to have
a
dynamic proxy generator (that would also help with DataSourceComponet
too...).
It would wrap the interface to enable garbage collection of components.
All a
client is responsible for is to request the component.

Anyway I am open to comments now.


--

"They that give up essential liberty to obtain a little temporary safety
 deserve neither liberty nor safety."
                - Benjamin Franklin


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


Re: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Peter Donald <pe...@apache.org>.
At 06:41 PM 6/7/2002 -0700, you wrote:
>With a combination of dynamic proxies and the Object.finalize() method
>it should be possible to use the VM's garbage collector to release a
>component.  This would be transparent to both the client and the
>component.

+1

This is what excalibur does except it also has an invalidate (rather than 
finalize) to do the work and it also invalidates the proxy aswell (making 
it impossible to use a deleted componet).


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


RE: [Design] ContainerManager is under fire--let's find the bestresolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Leo Simons [mailto:leosimons@apache.org] 
> one more thing:
> 
> Why is a role a string?
> -----------------------
> Because strings are easy for humans.
> 
> consider:
> 
> interface ComponentManager
> {
>     Object lookup(Role role);
>     boolean exists(role role);
> }
> 
> or even:
> 
> interface ComponentManager
> {
>     Object lookup(Object role);
>     boolean exists(Object role);
> }
> 
> and what we have is basically a read-only HashMap with a 
> specific contract and no unneccessary "convenience" methods.

Yes, but sometimes we need the hint.  Don't remove that ability.


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


Re: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Leo Simons <le...@apache.org>.
> Therefore, I suggest we come together on how we lookup and use our
> components. 

of course, I personally feel this discussion belongs on avalon-dev and
all interested should join us here =)

> Which raises two very good points.  How should we handle the CM
> interface,
> and do we need exceptions?
> 
> As a result, I would like to go back to grass roots, with a couple
> modifications.

I love it when a plan comes together =)

> Here is the interface for the CM:
> 
> interface ComponentManager
> {
>     Object lookup(String role);
>     Object lookup(String role, Object hint);
>     boolean exists(String role);
>     boolean exists(String role, Object hint);
> }

+1.

> 1) We return Object instead of Component.  This merges the lessons
> learned from
>    the ServiceManager discussions about accessing legacy components that
> are not
>    able to emplement the Component interface.

a "duh" for me by now =)

> 2) We remove all *declared* exceptions.  If there is something wrong, it
> is more
>    appropriate to throw a RuntimeException.

The removal of ComponentException essentially says that the only
exception ever to occur during lookup is the requested component not
being there. If there are others, all this falls to pieces. I don't
think there are though.

> 3) We add an additional lookup and hasComponent method (role, hint
> combination).

While not really neccesary in practice (you can tweak the role to
include whatever 'hint' you have), it is clean, and as long as it is
optional, it won't hurt me ;)

> 4) We remove the release() method altogether.

hurray!

> What will require some convincing--esp. to the Cocoon crew is the
> removal of
> the release() method.  To that end, read the last section.

snipping hideously complex explanation...summarising very briefly:

***pooling should not be the concern of the ComponentManager***

Pooling *can be* the concern of the container. Or it can be the
responsibility of the client application, or of a third-party API (ie
JDBC driver with built-in pooling).

If you remove pooling (or less specific perfomance-related) concerns
from the ComponentManager, release() is unneccessary.

Need pooling? -->

if( cm.exists( MyPool.ROLE ) )
{
	myObj = cm.lookup( MyPool.ROLE ).getInstance();
	myObj.doStuff();
	myObj.release();
}

there can only be discussion when you make pooling the concern of the
CM. I think this is improper SoC.

one more thing:

Why is a role a string?
-----------------------
Because strings are easy for humans.

consider:

interface ComponentManager
{
    Object lookup(Role role);
    boolean exists(role role);
}

or even:

interface ComponentManager
{
    Object lookup(Object role);
    boolean exists(Object role);
}

and what we have is basically a read-only HashMap with a specific
contract and no unneccessary "convenience" methods.

regards,

- Leo



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
Hi Robert,

> From: Robert Mouat [mailto:robert@mouat.net]
> 
> On Sat, 8 Jun 2002, Leo Sutic wrote:
> 
> > > From: Robert Mouat [mailto:robert@mouat.net]
> > >
> > > - relies on the VM's GC to return the component to the pool,
> > > and it is unclear how long this will take.
> > -1 for that reason.
> 
> The CM's lookup/release pair remind me a lot of the new/delete pair --
> which we don't have in Java because the VM does the 'delete' for us.
> 
> If it is ok to let the VM reclaim memory assigned to objects without
> having much control over the process, why is there a problem applying
this
> approach to reclaiming components for a pool?

You could buy 2Gb RAM and it won't cost a fortune, but you may fail to
buy enough licenses to create so many (licensed) components to fill
these 2Gb.

Same argument may apply to pool of any other components which utilize
some hardware resources which are more limited than memory (say, sockets
- you have just ~65536 of them (never counted them...)).

Java GC kicks in when memory is low; Pool GC must kick in when pool is
low. Can you control this efficiently enough to remove release method?


> couldn't the same arguments work in each case?

I'm not sure because of argument above.

Vadim


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Robert Mouat <ro...@mouat.net>.
On Sat, 8 Jun 2002, Leo Sutic wrote:

> > From: Robert Mouat [mailto:robert@mouat.net] 
> >
> > - relies on the VM's GC to return the component to the pool, 
> > and it is unclear how long this will take.
> -1 for that reason.

The CM's lookup/release pair remind me a lot of the new/delete pair --
which we don't have in Java because the VM does the 'delete' for us.

If it is ok to let the VM reclaim memory assigned to objects without
having much control over the process, why is there a problem applying this
approach to reclaiming components for a pool?

couldn't the same arguments work in each case?

> >  [I don't know 
> > much about GC implementations, but theoretically if there are 
> > no circular references the reference count could become 0 and 
> > the VM could remove the object immediately]
> Yes, but then we are making assumptions at how GC is implemented 
> in VMs. It is perfectly legal for a VM to not GC until it has filled
> the heap completely. So if you start with a heap of 5MB and has a
> heap max of 2GB, GC may not kick in until you have reached that upper
> limit.

so, the better the VM the better the performance... :)

If the only reason for using pools is performance then some tuning is to
be expected whenever they are used (e.g. determining the pool size).  
This tuning is going to be dependent on implementation (e.g. different
implementations will require different pool sizes for best performance).

Is there a reason to expect a significant performance difference between a
pool tuned for an explicit release(), and a pool tuned for using the VM's
garbage collection to do the release?

I'll admit that with a explicit release() it might be possible to tune a
pool for use with all VMs, while a GC release() will potentially need to
be tuned for each VM -- but isn't it reasonable to expect the
administrator/deployer of an application to perform some tuning to suit
their environment (especially if they are concerned about performance).

finally, if a pool runs out of components there is nothing stopping it
from running the garbage collector itself [though again, this would need
tuning -- but might make reduce the differences between VMs].

Robert.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Robert Mouat [mailto:robert@mouat.net] 
>
> - relies on the VM's GC to return the component to the pool, 
> and it is unclear how long this will take.

-1 for that reason.

>  [I don't know 
> much about GC implementations, but theoretically if there are 
> no circular references the reference count could become 0 and 
> the VM could remove the object immediately]

Yes, but then we are making assumptions at how GC is implemented 
in VMs. It is perfectly legal for a VM to not GC until it has filled
the heap completely. So if you start with a heap of 5MB and has a
heap max of 2GB, GC may not kick in until you have reached that upper
limit.

Too much uncertainty.

/LS


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


Re: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Robert Mouat <ro...@mouat.net>.
<delurk/>

On Thu, 6 Jun 2002, Berin Loritsch wrote:

<snip/>

> interface ComponentManager
> {
>     Object lookup(String role);
>     Object lookup(String role, Object hint);
>     boolean exists(String role);
>     boolean exists(String role, Object hint);
> }
> 
> If you notice, there are four distinct differences from the current
> ComponentManger:

<snip/>

> 4) We remove the release() method altogether.

With a combination of dynamic proxies and the Object.finalize() method
it should be possible to use the VM's garbage collector to release a
component.  This would allow the removal of the release() method, while
still guaranting that the component wasn't released until after the client
had finished using it.

how this would work:

- cm.lookup() returns a dynamic proxy implementing the interfaces of
the desired component.  This proxy will pass all interface calls onto
the real component.

- neither the container nor the component manager keep a reference to
the proxy (they are allowed a weak reference -- but we want the VM's
GC to tell us when the client nolonger holds a reference to it.

- the client uses the component (transparently via the proxy).

- when the client loses all references to the proxy the GC will call
the finalize() method on the proxy.  This method will do what the
cm.release() method currently does.

[note: it is the proxy that gets garbage collected, not the component]


how the code might look:

  class ReleasingProxy implements java.lang.reflect.InvocationHandler
  {

    private Object component;

    public ReleasingProxy( Object o )
    {
      component = o;
    }

    public Object invoke( Object proxy, Method method, Object[] args ) 
      throws Throwable
    {
      try
      {
        return method.invoke( component, args );
      }
      catch ( InvocationTargetException e )
      {
        throw e.getTargetException();
      }
    }  

    protected void finalize()
    {
      // code from cm.release() goes here.
    }

  }


in the lookup code 'return component;' can be replaced with:

  // may want to filter out the lifecycle interfaces...
  // they don't hurt, but it might be nice if they weren't
  // exposed to the client
  Class[] interfaces = component.getClass().getInterfaces();

  return java.lang.reflect.Proxy.newProxyInstance(
      classLoader,
      interfaces,
      new ReleasingProxy( component )
    );

[note: the ReleasingProxy will probably also need a reference to the
Container for doing the release]

Advantages:

- everything happens transparently to the client and component.

- the release code is only called after the client has lost all
references to the proxy (this actually makes it safer than using
cm.release())

Disadvantages:

- the release code is only called after the client has lost all
references to the proxy.

- relies on the VM's GC to return the component to the pool, and it is
unclear how long this will take.  [I don't know much about GC
implementations, but theoretically if there are no circular references
the reference count could become 0 and the VM could remove the object
immediately]

- requires JDK 1.3+

Robert.



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Andy Lewis <aj...@ascii27.net>.
I really like the philosophy behind what Berin is proposing here. You do
need to understand the lifecycle you are working in for component usage,
but how is that new....
>
>
>> From: Berin Loritsch [mailto:bloritsch@apache.org]
>>
>> > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
>> >
>> > Berin,
>> >
>> > I am 75% for your new CM interface. The problem is point 4.
>>
>> Am I not a prophet?
>
> :)
>
>> > Assume you have a CM that automatically reclaims all
>> > components after each request. That is, for Cocoon, when the
>> > request comes in, the CM starts keeping track of what
>> > components have been taken out, and when the request has been
>> > processed, they are release()'d (or equivalent method).
>> >
>> > Now introduce pooled components.
>> >
>> >     If more than pool-max components are looked-up during
>> >     the request you are not performing well, as you empty
>> >     the pool.
>>
>> I thought I already did introduce pooled components.  It's
>> really simple.  The GC process for components releases
>> them--just like we currently do. The GC process is done
>> after the Response is committed.
>
> The scenario was when more than pool-max lookups had been
> done before the GC kicks in. Suppose you have a pool-max of 3:
>
>   public void handleRequest () {
>      someMethod ();
>      someMethod ();
>      someMethod ();
>      someMethod ();
>   }
>
>   public void someMethod () {
>      manager.lookup (ExpensiveButPooledComponent.ROLE);
>      ...
>   }
>

This is why I replied - please don't take offense, but why on earth would
you could it this way?!?! That sets of all kinds of personal warning flags
of programming practice for me. The framework can't and shouldn't make up
for an inefficient compoenent - and your example here looks to be exactly
that - very inefficient.
I'm am struggling with a real-world example of why you would NEED to do
something htis way...if you have one, please provide it...

> With an explicit release() this could be made not to drain the pool.
> With GC you can not, unless you set the timeout ridiculously low.
>
<snip/>



-- 
"The heights of genius are only measurable by the depths of stupidity."



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


component construction & destruction concern (RE: [Design] ContainerManager is under fire--let's find the best resolution)

Posted by Leo Simons <le...@apache.org>.
up front summary: construction/destruction is not the concern of the CM,
but of the Container. The framework lifecycle interface associated with
destruction is Disposable. 

> > <snip>
> > 
> > So, from an elegance point of view, it makes perfect sense, for Avalon,
> > to provide aspect-oriented construction strategies *and* aspect-oriented
> > destruction strategies.
> +1000

This indeed makes perfect sense. Good analysis (including the <snip>ped
bits)!

> > Just like it's the component manager's concern to construct your
> > component the way the component was instructed to (depending on the
> > interfaces it implements), similarely, it should be the component
> > manager's concern (or some proxy slave, that's an implementation detail)
> > to dispose the component, depending on the disposing strategy that the
> > component implements.
> +1000 again
Here is where the doubts are. Is it the ComponentManagers concern to
construct / destruct your Component? 

No, that's the Container. The ComponentManager is one of the
communication mechanisms between container and contained component,
aimed at providing components with references to other components. 

How should a Container determine when a Component can be destructed?
What is the contract for this? 

simple: when the Component has run through its lifecycle it can be
safely destructed. 

Flow: 

// in SomeContainer: 

SomePool.start(); 

SomeCM.put( SomePool, SomePool.ROLE, SomePool.SOME_HINT ); 

// construction concern 
component.compose( SomeCM ); 
component.initialize(); 

// program flow concern 
component.start(); 
component.stop(); 

// destruction concern 
component.dispose(); 

SomeCM = null; // GC's a bitch 
SomePool.stop(); SomePool.dispose(); // release all 
SomePool = null; // GC's a bitch 

// in SomeComponent: 
compose( ComponentManager cm ) 
{ 
if(cm.exists(SomePool.ROLE, SomePool.SOME_HINT) 
m_pool = (Pool)ComponentManager.lookup(SomePool.ROLE, 
SomePool.SOME_HINT); 
} 
initialize() 
{ 
m_poolInstance = m_pool.getInstance(); 
} 
start() 
{ 
m_poolInstance.doStuff(); 
} 
stop() 
{ 
m_poolInstance.stopDoingStuff(); 
} 
dispose() 
{ 
m_pool.release(m_poolInstance); 
} 

Now for transparant pooling: 

SomePerformantComponent.start(); 

// in SomeContainer: 
SomeCM.put( SomePerformantComponent, SomePerformantComponent.ROLE, 
SomePerformantComponent.SOME_HINT ); 

component.compose( SomeCM ); 
component.initialize(); 
component.start(); 
component.stop(); 
component.dispose(); 

SomeCM = null; // GC's a bitch 
SomePerformantComponent.stop(); SomePerformantComponent.dispose(); 
SomePerformantComponent = null; // GC's a bitch 

// in SomeComponent: 
compose( ComponentManager cm ) 
{ 
if(cm.exists(SomePerformantComponent.ROLE, 
SomePerformantComponent.SOME_HINT) 
m_comp = (Pool)ComponentManager.lookup( 
SomePerformantComponent.ROLE, 
SomePerformantComponent.SOME_HINT); 
} 
initialize() 
{ 
} 
start() 
{ 
m_comp.doStuff(); 
} 
stop() 
{ 
m_comp.stopDoingStuff(); 
} 
dispose() 
{ 
} 

// in SomePerformantComponent: 

/* implement pooling here */ 

Sure enough, the container has a tough job (especially as it might be
the one actually doing the pooling on a poolable component) , but the
result is a simple client API.

cheers,

- Leo



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Carsten Ziegeler <cz...@s-und-n.de>.
Stefano Mazzocchi wrote:
> <snip/>
> 
> So, it makes perfect sense to merge the two aspects into a single CM.
+1

> <snip/>
> 
> You know what? I'm starting to think that the java GC is a gigantic
> mistake. Why? simple, it's useless.
> 
I totally agree here - before I started Java programming I used many
other languages where you explicitly have to care about object disposal.
If you follow one or two strict rules, you don't have any problems and
really do not need a GC - but let's focus on the topic again. Java has
a GC - and we will not change it, anyway.

> A GC continue to skeep thru your object space to look for 'detached'
> objects. That's a great implementation, but what if I forgot to 'detach'
> those objects?
> 
> If GC was that effective, why Java programs leak memory anyway?
> 
> Some people believe that Java is inherently safer than C because it has
> garbage collection that prevents people from shooting themselves in the
> foot with direct pointers to memory.
> 
> WRONG!
> 
Exactly!

> <snip>
> 
> So, from an elegance point of view, it makes perfect sense, for Avalon,
> to provide aspect-oriented construction strategies *and* aspect-oriented
> destruction strategies.
+1000

> 
> Just like it's the component manager's concern to construct your
> component the way the component was instructed to (depending on the
> interfaces it implements), similarely, it should be the component
> manager's concern (or some proxy slave, that's an implementation detail)
> to dispose the component, depending on the disposing strategy that the
> component implements.
+1000 again

Carsten

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


Re: [Design] ContainerManager is under fire--let's find the best resolution

Posted by "Andrew C. Oliver" <ac...@apache.org>.
Stefano Mazzocchi wrote:

>You are telling me that instead of doing 
>
> ConnectionPool pool = new ConnectionPool(...);
>
>you like to do
>
> ConnectionPool pool = (ConnectionPool) factory.create("connection
>pool");
>  
>
Yuck.  

Better:
ConnectionPool pool = (ConnectionPool) factory.create( 
ConnectionPool.class );

>Despite the obvious type unfafetyness introduced, admittedly, this is a
>step forward in the control of pooled objects.
>  
>
I prefer subclasses.  Granted I don't have intimate knowledge of that 
code yet, but the above signature
gives me chills.

>Now, you (and Berin) were suggesting that the CM be extended to provide
>a single point of contruction control not only for Avalon components,
>but also for those legacy objects that might request non-simple
>contruction control (such as pooled resources).
>
>I'm still very skeptical this is a good thing to do, it seems to be
>blurrying the component concept way too much.
>  
>
I think you're right.

>  
>
>>In my CM the "factories" make the bridge between the CM/framework and the
>>components. The "component factories" define:
>> - How a component is obtained;
>> - How it is released;
>> - What is its lifestyle and other "details" that the CM must know.
>>    
>>
+1 - which a generic factory can't do.  

ConnectionPool = ConnectionPoolFactory.create();
ConnectionPool = 
(ConnectionPool)factory.create(ConnectionPoolFactory.getInstance());

I'm of the general opinion that you know your right when you don't have 
to cast.  (with only a million
exceptions to the rule but as a general principal its sound).

>>No marker interfaces.
>>
>>This makes it MUCH simpler to have a lot of components/parts that are
>>independent from the CM/framework but that can be used by the CM/framework
>>with a minimum of coding.
>>    
>>
>
>Hmmm, I have to think about this some more.
>
>  
>

-Andy


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


Re: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Nicola Ken Barozzi <ni...@apache.org>.
Can't we just stop crossposting?

Who wants to follow the discussion gets on the Avalon list.

avalon-dev-subscribe@jakarta.apache.org

-- 
Nicola Ken Barozzi                   nicolaken@apache.org
            - verba volant, scripta manent -
   (discussions get forgotten, just code remains)
---------------------------------------------------------------------


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Stefano Mazzocchi [mailto:stefano@apache.org] 
> 
> Now, you (and Berin) were suggesting that the CM be extended 
> to provide a single point of contruction control not only for 
> Avalon components, but also for those legacy objects that 
> might request non-simple contruction control (such as pooled 
> resources).

Stefano, You missed the last discussion we had on the subject
back in January (if I recall correctly).  There is a good backgrounder
on the discussion and rationalization of using Object instead of
Component.

The fact of the matter is that if you describe the component
model correctly in terms of parents, children, and peers; then
you don't need to name your compoennts "Component".

Consider the CORBA architecture.  It is a component architecture,
as is EJBs.  Both of them have their lookup mechanisms--but if we
want to use them directly in an Avalon system, then we have to
be able to either generate proxy objects to implement Component
or we have to modify the original sourcecode.  That's a lot of
work to enable the seamless integration with legacy component
systems.  CORBA components can be accessed via JNDI just as EJB
components.  Why should we place an artificial limitation on
Avalon components that no other public component architecture
does?

The ServiceManager already exists, it represents what we want--
read more than just Cocoon.  It isn't going to change, and it
solves a lot of problems without introducing any of serious
consequence.


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


Re: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Stefano Mazzocchi <st...@apache.org>.
Paulo Gaspar wrote:
> 
> Sorry for the REALLY LATE answer. I have been a bit away:
> 
> > -----Original Message-----
> > From: Stefano Mazzocchi [mailto:stefano@apache.org]
> > Sent: Saturday, June 08, 2002 3:04 PM
> >
> > Paulo Gaspar wrote:
> > >
> > > About Object instead of Component...
> >
> > ...
> >
> > > I am using a CM similar in concept to the one Berin is
> > proposing for many
> > > months already (I think it will be one year in October) and
> > getting rid of
> > > Component and the other marker interfaces was one of my best decisions.
> > >
> > > The Component interface is a major PITA when you want to reuse existing
> > > components.
> >
> > "classes", if you want to reuse existing 'classes'.
> 
> Stefano, if I use them as components, why do I have to keep calling them
> classes. As far as I can see they were already used as Components before
> being integrated into a framework.
> 
> Now, I can accept that I am wrong... if you just tell me WHY!
> 
> Explain me the vocabulary model you use and I might adopt it.

If it was possible to have Avalon hook into the java object creation
mechanism, than 'component == class', unfortunately, this is not
possible.

I call an 'avalon component' something that implements avalon classes
and it is created and managed with the avalon lifecycle model.

A class is something that doesn't do that. (note: if you instantiate an
avalon component with 'new', then it's not a component anymore, it's
downgraded at a class in my terminology)

This is why lookup() returned 'Component': it was a way to tell you that
what was returned was something that went thru the avalon lifecycle.

Conceptually, I still don't like the change between Component and
Object, but I *do* understand the value of usability so I'm not
deadlocking the process with stubborn -1s on this.

> > > Example: if I have a Database Connection Pool independent from
> > Avalon that
> > > I want to use with an Avalon CM, I will have to either:
> > >  - Have and change the DB Pool source in order for it to return
> > Connection
> > >    objects that implement Component;
> > > or
> > >  - Wrap the DataSource objects with my own DataSource that wraps the
> > >    originaly returned Connection with a proxy Connection that implements
> > >    Component.
> > >
> > > With my CM I just need to implement a factory for the DB Connection pool
> > > and the reason I can do that is because my CM uses neither Component nor
> > > other marker interfaces.
> >
> > You are telling me that instead of doing
> >
> >  ConnectionPool pool = new ConnectionPool(...);
> >
> > you like to do
> >
> >  ConnectionPool pool = (ConnectionPool) factory.create("connection
> > pool");
> 
> Not really.
> 
> We are talking about:
> 
>   ConnectionPool pool = (ConnectionPool)
>       myComponentManager.lookup("ConnectionPool", "myConnectionPool")
> 
> or something like that. But behind the scenes there is a component
> "factory" that both creates/returns an usable component instance AND
> defines its life style. Actually, this "factory" is a replacement for
> the Avalon's current ComponentHandler.
> 
> The big difference for the current Avalon model is that you are able to
> define a custom "ComponentHandler" for each role and that the
> "ComponentHandler" is the one defining the lifestyle, not the marker
> interfaces of the Component.
> 
> In my framework the "ComponentHandler" must say something about the
> lifestyle to the "ComponentManager" because my CM's component tracking.
> (The component tracking allows th CM to release all the components used
> on a "request", or all the components still "away" on shutdown.)
> 
> > Despite the obvious type unfafetyness introduced, admittedly, this is a
> > step forward in the control of pooled objects.
> >
> > Now, you (and Berin) were suggesting that the CM be extended to provide
> > a single point of contruction control not only for Avalon components,
> > but also for those legacy objects that might request non-simple
> > contruction control (such as pooled resources).
> 
> Well, it is not really the CM. The CM just keeps the whole thing together
> hiding to the user the uglies of component creation/management.
> 
> > I'm still very skeptical this is a good thing to do, it seems to be
> > blurrying the component concept way too much.
> 
> Why?

explained above. But again, I'm not stopping this from happening if you
see uses for it.
 
> > > In my CM the "factories" make the bridge between the
> > CM/framework and the
> > > components. The "component factories" define:
> > >  - How a component is obtained;
> > >  - How it is released;
> > >  - What is its lifestyle and other "details" that the CM must know.
> > >
> > > No marker interfaces.
> > >
> > > This makes it MUCH simpler to have a lot of components/parts that are
> > > independent from the CM/framework but that can be used by the
> > CM/framework
> > > with a minimum of coding.
> >
> > Hmmm, I have to think about this some more.
> 
> Did yo ualready?
> =;o)

yes, I did :)

-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<st...@apache.org>                             Friedrich Nietzsche
--------------------------------------------------------------------



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Paulo Gaspar <pa...@krankikom.de>.
Sorry for the REALLY LATE answer. I have been a bit away:

> -----Original Message-----
> From: Stefano Mazzocchi [mailto:stefano@apache.org]
> Sent: Saturday, June 08, 2002 3:04 PM
>
> Paulo Gaspar wrote:
> >
> > About Object instead of Component...
>
> ...
>
> > I am using a CM similar in concept to the one Berin is
> proposing for many
> > months already (I think it will be one year in October) and
> getting rid of
> > Component and the other marker interfaces was one of my best decisions.
> >
> > The Component interface is a major PITA when you want to reuse existing
> > components.
>
> "classes", if you want to reuse existing 'classes'.

Stefano, if I use them as components, why do I have to keep calling them
classes. As far as I can see they were already used as Components before
being integrated into a framework.

Now, I can accept that I am wrong... if you just tell me WHY!

Explain me the vocabulary model you use and I might adopt it.


> > Example: if I have a Database Connection Pool independent from
> Avalon that
> > I want to use with an Avalon CM, I will have to either:
> >  - Have and change the DB Pool source in order for it to return
> Connection
> >    objects that implement Component;
> > or
> >  - Wrap the DataSource objects with my own DataSource that wraps the
> >    originaly returned Connection with a proxy Connection that implements
> >    Component.
> >
> > With my CM I just need to implement a factory for the DB Connection pool
> > and the reason I can do that is because my CM uses neither Component nor
> > other marker interfaces.
>
> You are telling me that instead of doing
>
>  ConnectionPool pool = new ConnectionPool(...);
>
> you like to do
>
>  ConnectionPool pool = (ConnectionPool) factory.create("connection
> pool");

Not really.

We are talking about:

  ConnectionPool pool = (ConnectionPool)
      myComponentManager.lookup("ConnectionPool", "myConnectionPool")

or something like that. But behind the scenes there is a component
"factory" that both creates/returns an usable component instance AND
defines its life style. Actually, this "factory" is a replacement for
the Avalon's current ComponentHandler.

The big difference for the current Avalon model is that you are able to
define a custom "ComponentHandler" for each role and that the
"ComponentHandler" is the one defining the lifestyle, not the marker
interfaces of the Component.

In my framework the "ComponentHandler" must say something about the
lifestyle to the "ComponentManager" because my CM's component tracking.
(The component tracking allows th CM to release all the components used
on a "request", or all the components still "away" on shutdown.)


> Despite the obvious type unfafetyness introduced, admittedly, this is a
> step forward in the control of pooled objects.
>
> Now, you (and Berin) were suggesting that the CM be extended to provide
> a single point of contruction control not only for Avalon components,
> but also for those legacy objects that might request non-simple
> contruction control (such as pooled resources).

Well, it is not really the CM. The CM just keeps the whole thing together
hiding to the user the uglies of component creation/management.


> I'm still very skeptical this is a good thing to do, it seems to be
> blurrying the component concept way too much.

Why?


> > In my CM the "factories" make the bridge between the
> CM/framework and the
> > components. The "component factories" define:
> >  - How a component is obtained;
> >  - How it is released;
> >  - What is its lifestyle and other "details" that the CM must know.
> >
> > No marker interfaces.
> >
> > This makes it MUCH simpler to have a lot of components/parts that are
> > independent from the CM/framework but that can be used by the
> CM/framework
> > with a minimum of coding.
>
> Hmmm, I have to think about this some more.

Did yo ualready?
=;o)


Have fun,
Paulo Gaspar


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Stefano Mazzocchi [mailto:stefano@apache.org] 
> 
> Now, you (and Berin) were suggesting that the CM be extended 
> to provide a single point of contruction control not only for 
> Avalon components, but also for those legacy objects that 
> might request non-simple contruction control (such as pooled 
> resources).

Stefano, You missed the last discussion we had on the subject
back in January (if I recall correctly).  There is a good backgrounder
on the discussion and rationalization of using Object instead of
Component.

The fact of the matter is that if you describe the component
model correctly in terms of parents, children, and peers; then
you don't need to name your compoennts "Component".

Consider the CORBA architecture.  It is a component architecture,
as is EJBs.  Both of them have their lookup mechanisms--but if we
want to use them directly in an Avalon system, then we have to
be able to either generate proxy objects to implement Component
or we have to modify the original sourcecode.  That's a lot of
work to enable the seamless integration with legacy component
systems.  CORBA components can be accessed via JNDI just as EJB
components.  Why should we place an artificial limitation on
Avalon components that no other public component architecture
does?

The ServiceManager already exists, it represents what we want--
read more than just Cocoon.  It isn't going to change, and it
solves a lot of problems without introducing any of serious
consequence.


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


Re: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Stefano Mazzocchi <st...@apache.org>.
Paulo Gaspar wrote:
> 
> About Object instead of Component...

...

> I am using a CM similar in concept to the one Berin is proposing for many
> months already (I think it will be one year in October) and getting rid of
> Component and the other marker interfaces was one of my best decisions.
> 
> The Component interface is a major PITA when you want to reuse existing
> components.

"classes", if you want to reuse existing 'classes'.

> Example: if I have a Database Connection Pool independent from Avalon that
> I want to use with an Avalon CM, I will have to either:
>  - Have and change the DB Pool source in order for it to return Connection
>    objects that implement Component;
> or
>  - Wrap the DataSource objects with my own DataSource that wraps the
>    originaly returned Connection with a proxy Connection that implements
>    Component.
> 
> With my CM I just need to implement a factory for the DB Connection pool
> and the reason I can do that is because my CM uses neither Component nor
> other marker interfaces.

You are telling me that instead of doing 

 ConnectionPool pool = new ConnectionPool(...);

you like to do

 ConnectionPool pool = (ConnectionPool) factory.create("connection
pool");

Despite the obvious type unfafetyness introduced, admittedly, this is a
step forward in the control of pooled objects.

Now, you (and Berin) were suggesting that the CM be extended to provide
a single point of contruction control not only for Avalon components,
but also for those legacy objects that might request non-simple
contruction control (such as pooled resources).

I'm still very skeptical this is a good thing to do, it seems to be
blurrying the component concept way too much.

> In my CM the "factories" make the bridge between the CM/framework and the
> components. The "component factories" define:
>  - How a component is obtained;
>  - How it is released;
>  - What is its lifestyle and other "details" that the CM must know.
> 
> No marker interfaces.
> 
> This makes it MUCH simpler to have a lot of components/parts that are
> independent from the CM/framework but that can be used by the CM/framework
> with a minimum of coding.

Hmmm, I have to think about this some more.

-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<st...@apache.org>                             Friedrich Nietzsche
--------------------------------------------------------------------



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


Re: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Stefano Mazzocchi <st...@apache.org>.
Paulo Gaspar wrote:
> 
> About Object instead of Component...

...

> I am using a CM similar in concept to the one Berin is proposing for many
> months already (I think it will be one year in October) and getting rid of
> Component and the other marker interfaces was one of my best decisions.
> 
> The Component interface is a major PITA when you want to reuse existing
> components.

"classes", if you want to reuse existing 'classes'.

> Example: if I have a Database Connection Pool independent from Avalon that
> I want to use with an Avalon CM, I will have to either:
>  - Have and change the DB Pool source in order for it to return Connection
>    objects that implement Component;
> or
>  - Wrap the DataSource objects with my own DataSource that wraps the
>    originaly returned Connection with a proxy Connection that implements
>    Component.
> 
> With my CM I just need to implement a factory for the DB Connection pool
> and the reason I can do that is because my CM uses neither Component nor
> other marker interfaces.

You are telling me that instead of doing 

 ConnectionPool pool = new ConnectionPool(...);

you like to do

 ConnectionPool pool = (ConnectionPool) factory.create("connection
pool");

Despite the obvious type unfafetyness introduced, admittedly, this is a
step forward in the control of pooled objects.

Now, you (and Berin) were suggesting that the CM be extended to provide
a single point of contruction control not only for Avalon components,
but also for those legacy objects that might request non-simple
contruction control (such as pooled resources).

I'm still very skeptical this is a good thing to do, it seems to be
blurrying the component concept way too much.

> In my CM the "factories" make the bridge between the CM/framework and the
> components. The "component factories" define:
>  - How a component is obtained;
>  - How it is released;
>  - What is its lifestyle and other "details" that the CM must know.
> 
> No marker interfaces.
> 
> This makes it MUCH simpler to have a lot of components/parts that are
> independent from the CM/framework but that can be used by the CM/framework
> with a minimum of coding.

Hmmm, I have to think about this some more.

-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<st...@apache.org>                             Friedrich Nietzsche
--------------------------------------------------------------------



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Paulo Gaspar <pa...@krankikom.de>.
About Object instead of Component...

> -----Original Message-----
> From: Stefano Mazzocchi [mailto:stefano@apache.org]
> Sent: Friday, June 07, 2002 12:18 AM
> 
> Gosh, I forgot how strident can become talking about high level
> abstractions... remind me of the good old days when we were discussing
> what later became known as Avalon and Pier and I got such a huge fight
> for a simple method.
> 
> ihihih, discussing such high-level abstractions can get really nasty
> ego-wise :)
> 
> Berin Loritsch wrote:
> > 
> > > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > >
> > > > From: Berin Loritsch [mailto:bloritsch@apache.org]
> 
> blah blah blah
> 
> Let's clear up the table.
> 
> Berin is proposing a better CM and I like it more than what Avalon 4
> has. First of all, it removes that stupid "pass non-exceptional info
> with exceptions" design pattern.
> 
> Ah, BTW, there are *tons* of places where this happens in Avalon,
> please, make sure the above anti-pattern is removed from Avalon 5.
> 
> Then it removes the need for that hacky ComponentSelector, unifying
> approaches.
> 
> Anyway, despite a few issues I'm having (I don't see why we should
> return an Object instead of a Component. That's a component selector,
> not an object selector. There is the Class object for that!) I see it as
> a step forward.
 
I am using a CM similar in concept to the one Berin is proposing for many
months already (I think it will be one year in October) and getting rid of
Component and the other marker interfaces was one of my best decisions.

The Component interface is a major PITA when you want to reuse existing
components. 

Example: if I have a Database Connection Pool independent from Avalon that
I want to use with an Avalon CM, I will have to either:
 - Have and change the DB Pool source in order for it to return Connection
   objects that implement Component;
or
 - Wrap the DataSource objects with my own DataSource that wraps the 
   originaly returned Connection with a proxy Connection that implements
   Component.


With my CM I just need to implement a factory for the DB Connection pool
and the reason I can do that is because my CM uses neither Component nor
other marker interfaces.


In my CM the "factories" make the bridge between the CM/framework and the
components. The "component factories" define:
 - How a component is obtained;
 - How it is released;
 - What is its lifestyle and other "details" that the CM must know.

No marker interfaces.

This makes it MUCH simpler to have a lot of components/parts that are
independent from the CM/framework but that can be used by the CM/framework
with a minimum of coding.

 
> The problem is garbage collection of components.

Here we fully agree. I miss the release() methods.


Have fun,
Paulo Gaspar

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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Carsten Ziegeler <cz...@s-und-n.de>.
Stefano Mazzocchi wrote:
> <snip/>
> 
> So, it makes perfect sense to merge the two aspects into a single CM.
+1

> <snip/>
> 
> You know what? I'm starting to think that the java GC is a gigantic
> mistake. Why? simple, it's useless.
> 
I totally agree here - before I started Java programming I used many
other languages where you explicitly have to care about object disposal.
If you follow one or two strict rules, you don't have any problems and
really do not need a GC - but let's focus on the topic again. Java has
a GC - and we will not change it, anyway.

> A GC continue to skeep thru your object space to look for 'detached'
> objects. That's a great implementation, but what if I forgot to 'detach'
> those objects?
> 
> If GC was that effective, why Java programs leak memory anyway?
> 
> Some people believe that Java is inherently safer than C because it has
> garbage collection that prevents people from shooting themselves in the
> foot with direct pointers to memory.
> 
> WRONG!
> 
Exactly!

> <snip>
> 
> So, from an elegance point of view, it makes perfect sense, for Avalon,
> to provide aspect-oriented construction strategies *and* aspect-oriented
> destruction strategies.
+1000

> 
> Just like it's the component manager's concern to construct your
> component the way the component was instructed to (depending on the
> interfaces it implements), similarely, it should be the component
> manager's concern (or some proxy slave, that's an implementation detail)
> to dispose the component, depending on the disposing strategy that the
> component implements.
+1000 again

Carsten

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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Paulo Gaspar <pa...@krankikom.de>.
About Object instead of Component...

> -----Original Message-----
> From: Stefano Mazzocchi [mailto:stefano@apache.org]
> Sent: Friday, June 07, 2002 12:18 AM
> 
> Gosh, I forgot how strident can become talking about high level
> abstractions... remind me of the good old days when we were discussing
> what later became known as Avalon and Pier and I got such a huge fight
> for a simple method.
> 
> ihihih, discussing such high-level abstractions can get really nasty
> ego-wise :)
> 
> Berin Loritsch wrote:
> > 
> > > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > >
> > > > From: Berin Loritsch [mailto:bloritsch@apache.org]
> 
> blah blah blah
> 
> Let's clear up the table.
> 
> Berin is proposing a better CM and I like it more than what Avalon 4
> has. First of all, it removes that stupid "pass non-exceptional info
> with exceptions" design pattern.
> 
> Ah, BTW, there are *tons* of places where this happens in Avalon,
> please, make sure the above anti-pattern is removed from Avalon 5.
> 
> Then it removes the need for that hacky ComponentSelector, unifying
> approaches.
> 
> Anyway, despite a few issues I'm having (I don't see why we should
> return an Object instead of a Component. That's a component selector,
> not an object selector. There is the Class object for that!) I see it as
> a step forward.
 
I am using a CM similar in concept to the one Berin is proposing for many
months already (I think it will be one year in October) and getting rid of
Component and the other marker interfaces was one of my best decisions.

The Component interface is a major PITA when you want to reuse existing
components. 

Example: if I have a Database Connection Pool independent from Avalon that
I want to use with an Avalon CM, I will have to either:
 - Have and change the DB Pool source in order for it to return Connection
   objects that implement Component;
or
 - Wrap the DataSource objects with my own DataSource that wraps the 
   originaly returned Connection with a proxy Connection that implements
   Component.


With my CM I just need to implement a factory for the DB Connection pool
and the reason I can do that is because my CM uses neither Component nor
other marker interfaces.


In my CM the "factories" make the bridge between the CM/framework and the
components. The "component factories" define:
 - How a component is obtained;
 - How it is released;
 - What is its lifestyle and other "details" that the CM must know.

No marker interfaces.

This makes it MUCH simpler to have a lot of components/parts that are
independent from the CM/framework but that can be used by the CM/framework
with a minimum of coding.

 
> The problem is garbage collection of components.

Here we fully agree. I miss the release() methods.


Have fun,
Paulo Gaspar

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


Re: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Stefano Mazzocchi <st...@apache.org>.
Gosh, I forgot how strident can become talking about high level
abstractions... remind me of the good old days when we were discussing
what later became known as Avalon and Pier and I got such a huge fight
for a simple method.

ihihih, discussing such high-level abstractions can get really nasty
ego-wise :)

Berin Loritsch wrote:
> 
> > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> >
> > > From: Berin Loritsch [mailto:bloritsch@apache.org]

blah blah blah

Let's clear up the table.

Berin is proposing a better CM and I like it more than what Avalon 4
has. First of all, it removes that stupid "pass non-exceptional info
with exceptions" design pattern.

Ah, BTW, there are *tons* of places where this happens in Avalon,
please, make sure the above anti-pattern is removed from Avalon 5.

Then it removes the need for that hacky ComponentSelector, unifying
approaches.

Anyway, despite a few issues I'm having (I don't see why we should
return an Object instead of a Component. That's a component selector,
not an object selector. There is the Class object for that!) I see it as
a step forward.


The problem is garbage collection of components.

                                   - o -

WARNING: radical changes ahead, this is not for the faint-hearted! YOU
HAVE BEEN WARNED!

Let's make one step back: what is an avalon component?

I'm pretty sure that everybody has a different idea on what this really
is, but here is my personal one: 

  an avalon components is the implementation of a functional description

[so far, is nothing different from a normal class implementing an
interface]

  and exposes behavioral modifiers

This is the difference between an Avalon component and a java class
implementing an interface: the way the class is created.

[the other differences are functional, not conceptual]

In Java, the only way to modify how a class is constructed is to call a
different constructor method. Unfortunately, java doesn't define
"construction prototypes" but only 'functional prototypes' (with
interfaces).

This left the original Avalon designers with one radical solution:
deprecate the use of constructors and create a totally different
construction lifecycle.

First, we thought about creating a ComponentFactory, something like

 public class ComponentFactory {
    Component createComponent(String componentName);
 }

but soon we realized that the ability to separate the concern of
creation from that of use, we could simply create pools of pre-created
objects. So, in that case, createComponent() was a bad name and Factory
too limiting.

This lead to the concept of a ComponentManager, the 'director' of the
'play', where each actor asks the director to indicate what person
performs a particular role in the play, in order to be able to
communicate with it.

The CM is also able to 'instruct' a new actor to perform a particular
role. So, from a design pattern point of view, "Manager extends
Factory".

We didn't think about role collisions: blinded by the 'play metaphor',
we thought that there was no need, on stage, for two actors acting the
same role with dressed up in different colors. On later thought, this is
not true: it is the rule that important carachters in the play has a
'backup'. In that case, an actor might ask not only the role played, but
also the 'hint' (official/backup) to obtain the reference to the other
actor.

So, it makes perfect sense to merge the two aspects into a single CM.

So far so good.

                                   - o -

Two steps back, now.

Before the introduction of automatic garbage collection, everybody
allocated memory, used it and freed it when it was not needed. Failing
to do the last part provided those infamous 'memory leaks' that almost
all programs in the world suffer.

In more abstracted languages where you don't have direct access to the
memory, you don't allocate it directly, but you create an functional
entity (object, for example), you use it, then you dispose it.

This is less error prone because it's more abstract, but still requires
people to know what they are doing and don't forget to dispose those
objects which aren't needed.

Enter garbage collection: at the price of a system overhead, the
programmer is released from the responsibility to provide explicit
disposal for the objects he creates.

You know what? I'm starting to think that the java GC is a gigantic
mistake. Why? simple, it's useless.

A GC continue to skeep thru your object space to look for 'detached'
objects. That's a great implementation, but what if I forgot to 'detach'
those objects?

If GC was that effective, why Java programs leak memory anyway?

Some people believe that Java is inherently safer than C because it has
garbage collection that prevents people from shooting themselves in the
foot with direct pointers to memory.

WRONG!

It's the absence of pointers that make Java safer, not the capability of
the VM to clean up your mess for you. It can't! It can't be smarter than
you no matter how hard you try! 

If I was to rewrite java from scratch I would simply make that stupid
and utterly useless

 Object.finalize()

method active and native instead of passive and empty! 

So, instead of doing

 HashMap map = new HashMap();
 map.add("a","1");
 map.add("b","2");

 ...

 map = null // let's make it ready for GC

you call your stinking

 map.finalize();

[much better names would be destroy(), dispose(), cleanup()]

that invalidates it and turns 'map' into a null and recursively
invalidates all those objects that are not bound to any other object
(this can be done asynchronously, but it's a VM implementation detail)

                                   - o -

Berin points out that people might forget to dispose thier components,
thus producing leaks. If made automatic, component GC could eliminate
this problem entirely and make it easier to use Avalon.

I agree on the intention but I question the effectiveness of the
approach: Java has shown that GC doesn't eliminate memory leaks because
the program has no way to interact with the garbage generation strategy
of the JVM.

This was somewhat changed with WeakReferences: the GC treats objects and
weakobjects differently. Unfortunately, these are hardcoded GC
strategies and there is no way to create ThreadGroupObjects or other
similar GC strategy aspects.

It's evident: the java architects didn't bother much at making object
construction strategies more aspect oriented, and they did the same with
object destruction.

So, from an elegance point of view, it makes perfect sense, for Avalon,
to provide aspect-oriented construction strategies *and* aspect-oriented
destruction strategies.

Just like it's the component manager's concern to construct your
component the way the component was instructed to (depending on the
interfaces it implements), similarely, it should be the component
manager's concern (or some proxy slave, that's an implementation detail)
to dispose the component, depending on the disposing strategy that the
component implements.

                                    - o -

The only concern I have is the fact that the dispose() method for the CM
might still be required for all those cases where the strategy might not
apply correctly, or for those cases where a strategy would need native
access to the JVM to fully obtain enough information to perform.

I think that even if we come up with a transparent component disposable
strategy framework, the dispose() method in the CM woudn't hurt and
would keep everybody happy.

-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<st...@apache.org>                             Friedrich Nietzsche
--------------------------------------------------------------------



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


Re: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Stefano Mazzocchi <st...@apache.org>.
Gosh, I forgot how strident can become talking about high level
abstractions... remind me of the good old days when we were discussing
what later became known as Avalon and Pier and I got such a huge fight
for a simple method.

ihihih, discussing such high-level abstractions can get really nasty
ego-wise :)

Berin Loritsch wrote:
> 
> > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> >
> > > From: Berin Loritsch [mailto:bloritsch@apache.org]

blah blah blah

Let's clear up the table.

Berin is proposing a better CM and I like it more than what Avalon 4
has. First of all, it removes that stupid "pass non-exceptional info
with exceptions" design pattern.

Ah, BTW, there are *tons* of places where this happens in Avalon,
please, make sure the above anti-pattern is removed from Avalon 5.

Then it removes the need for that hacky ComponentSelector, unifying
approaches.

Anyway, despite a few issues I'm having (I don't see why we should
return an Object instead of a Component. That's a component selector,
not an object selector. There is the Class object for that!) I see it as
a step forward.


The problem is garbage collection of components.

                                   - o -

WARNING: radical changes ahead, this is not for the faint-hearted! YOU
HAVE BEEN WARNED!

Let's make one step back: what is an avalon component?

I'm pretty sure that everybody has a different idea on what this really
is, but here is my personal one: 

  an avalon components is the implementation of a functional description

[so far, is nothing different from a normal class implementing an
interface]

  and exposes behavioral modifiers

This is the difference between an Avalon component and a java class
implementing an interface: the way the class is created.

[the other differences are functional, not conceptual]

In Java, the only way to modify how a class is constructed is to call a
different constructor method. Unfortunately, java doesn't define
"construction prototypes" but only 'functional prototypes' (with
interfaces).

This left the original Avalon designers with one radical solution:
deprecate the use of constructors and create a totally different
construction lifecycle.

First, we thought about creating a ComponentFactory, something like

 public class ComponentFactory {
    Component createComponent(String componentName);
 }

but soon we realized that the ability to separate the concern of
creation from that of use, we could simply create pools of pre-created
objects. So, in that case, createComponent() was a bad name and Factory
too limiting.

This lead to the concept of a ComponentManager, the 'director' of the
'play', where each actor asks the director to indicate what person
performs a particular role in the play, in order to be able to
communicate with it.

The CM is also able to 'instruct' a new actor to perform a particular
role. So, from a design pattern point of view, "Manager extends
Factory".

We didn't think about role collisions: blinded by the 'play metaphor',
we thought that there was no need, on stage, for two actors acting the
same role with dressed up in different colors. On later thought, this is
not true: it is the rule that important carachters in the play has a
'backup'. In that case, an actor might ask not only the role played, but
also the 'hint' (official/backup) to obtain the reference to the other
actor.

So, it makes perfect sense to merge the two aspects into a single CM.

So far so good.

                                   - o -

Two steps back, now.

Before the introduction of automatic garbage collection, everybody
allocated memory, used it and freed it when it was not needed. Failing
to do the last part provided those infamous 'memory leaks' that almost
all programs in the world suffer.

In more abstracted languages where you don't have direct access to the
memory, you don't allocate it directly, but you create an functional
entity (object, for example), you use it, then you dispose it.

This is less error prone because it's more abstract, but still requires
people to know what they are doing and don't forget to dispose those
objects which aren't needed.

Enter garbage collection: at the price of a system overhead, the
programmer is released from the responsibility to provide explicit
disposal for the objects he creates.

You know what? I'm starting to think that the java GC is a gigantic
mistake. Why? simple, it's useless.

A GC continue to skeep thru your object space to look for 'detached'
objects. That's a great implementation, but what if I forgot to 'detach'
those objects?

If GC was that effective, why Java programs leak memory anyway?

Some people believe that Java is inherently safer than C because it has
garbage collection that prevents people from shooting themselves in the
foot with direct pointers to memory.

WRONG!

It's the absence of pointers that make Java safer, not the capability of
the VM to clean up your mess for you. It can't! It can't be smarter than
you no matter how hard you try! 

If I was to rewrite java from scratch I would simply make that stupid
and utterly useless

 Object.finalize()

method active and native instead of passive and empty! 

So, instead of doing

 HashMap map = new HashMap();
 map.add("a","1");
 map.add("b","2");

 ...

 map = null // let's make it ready for GC

you call your stinking

 map.finalize();

[much better names would be destroy(), dispose(), cleanup()]

that invalidates it and turns 'map' into a null and recursively
invalidates all those objects that are not bound to any other object
(this can be done asynchronously, but it's a VM implementation detail)

                                   - o -

Berin points out that people might forget to dispose thier components,
thus producing leaks. If made automatic, component GC could eliminate
this problem entirely and make it easier to use Avalon.

I agree on the intention but I question the effectiveness of the
approach: Java has shown that GC doesn't eliminate memory leaks because
the program has no way to interact with the garbage generation strategy
of the JVM.

This was somewhat changed with WeakReferences: the GC treats objects and
weakobjects differently. Unfortunately, these are hardcoded GC
strategies and there is no way to create ThreadGroupObjects or other
similar GC strategy aspects.

It's evident: the java architects didn't bother much at making object
construction strategies more aspect oriented, and they did the same with
object destruction.

So, from an elegance point of view, it makes perfect sense, for Avalon,
to provide aspect-oriented construction strategies *and* aspect-oriented
destruction strategies.

Just like it's the component manager's concern to construct your
component the way the component was instructed to (depending on the
interfaces it implements), similarely, it should be the component
manager's concern (or some proxy slave, that's an implementation detail)
to dispose the component, depending on the disposing strategy that the
component implements.

                                    - o -

The only concern I have is the fact that the dispose() method for the CM
might still be required for all those cases where the strategy might not
apply correctly, or for those cases where a strategy would need native
access to the JVM to fully obtain enough information to perform.

I think that even if we come up with a transparent component disposable
strategy framework, the dispose() method in the CM woudn't hurt and
would keep everybody happy.

-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<st...@apache.org>                             Friedrich Nietzsche
--------------------------------------------------------------------



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


Re: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Michael Locasto <ml...@pfsmarketing.com>.
Hi,

I'm not entirely familiar with the internals of Cocoon, so please bear
with me. However, my main point is two-fold:

-there is a difference in practice between recycling reusable components
and "real" garbage collection
-are we sure that removing the responsibility for management of reusable
components from the developer will reduce complexity or support best
practices?

> With an explicit release() you are in the same boat as the GC
> method.  For Cocoon we have a really simple lifelength for
> requested components: the length of a request.  It's not that
> hard to implement or to comprehend.  It is also pretty easy
> to manage the instances available.

Admittedly, for Cocoon it may be very easy to tell when a call to the
recycler/GC is to be executed...but for other containers, is this
necessarily so? If not, it may lead to difficult management of GC/recycle
policy. Are we sure that we want to play "Indian-giver" with the
developer, who may think that since he has not explicitly released the
resource, he may still use it? What if the developer's process is some
sort of open-ended session or transaction?

> Are timeouts sufficient?  No.  Does it add additional
> complexity for the container? Yes.  Does it help the developer?
> absolutely.

IMHO, auto-magically returning things to the pool seems like a nice
feature of the container at first blush, but what it really does is
reinforce sloppy programming by the developer, or at least make him adjust
his mindset each time he switches between containers and their differing
policies. That's added complexity for the developer, not
less. The onus for returning borrowed resources should be on the
developer, because he best knows when he is finished using them.

I suppose I'm just stubbornly resistant to the idea of losing
responsibility for the objects running around in my
code. No, I guess I mean I don't want to lose *control* over those
objects. ;) From the developer's point of view,
it would be nice to know that objects I'm using won't disappear according
to some ad hoc recycling policy, but
it's also comforting to know the container will clean up after me if I'm
sloppy. Oh, the rock and the hard place...

Regards,
Michael



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


Re: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Michael Locasto <ml...@pfsmarketing.com>.
Hi,

I'm not entirely familiar with the internals of Cocoon, so please bear
with me. However, my main point is two-fold:

-there is a difference in practice between recycling reusable components
and "real" garbage collection
-are we sure that removing the responsibility for management of reusable
components from the developer will reduce complexity or support best
practices?

> With an explicit release() you are in the same boat as the GC
> method.  For Cocoon we have a really simple lifelength for
> requested components: the length of a request.  It's not that
> hard to implement or to comprehend.  It is also pretty easy
> to manage the instances available.

Admittedly, for Cocoon it may be very easy to tell when a call to the
recycler/GC is to be executed...but for other containers, is this
necessarily so? If not, it may lead to difficult management of GC/recycle
policy. Are we sure that we want to play "Indian-giver" with the
developer, who may think that since he has not explicitly released the
resource, he may still use it? What if the developer's process is some
sort of open-ended session or transaction?

> Are timeouts sufficient?  No.  Does it add additional
> complexity for the container? Yes.  Does it help the developer?
> absolutely.

IMHO, auto-magically returning things to the pool seems like a nice
feature of the container at first blush, but what it really does is
reinforce sloppy programming by the developer, or at least make him adjust
his mindset each time he switches between containers and their differing
policies. That's added complexity for the developer, not
less. The onus for returning borrowed resources should be on the
developer, because he best knows when he is finished using them.

I suppose I'm just stubbornly resistant to the idea of losing
responsibility for the objects running around in my
code. No, I guess I mean I don't want to lose *control* over those
objects. ;) From the developer's point of view,
it would be nice to know that objects I'm using won't disappear according
to some ad hoc recycling policy, but
it's also comforting to know the container will clean up after me if I'm
sloppy. Oh, the rock and the hard place...

Regards,
Michael



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Andy Lewis <aj...@ascii27.net>.
<snip/>

>
> Yes, if they share same ... how you call it? ... scope: both are
> ThreadSafe or Poolable (by nature). Here, one (Transformer) will be
> ThreadSafe (or even not a component (it's too lightweight for it)), and
> other (XMLSource) - Poolable.
>
> Thus, you can not keep an instance of XMLSource in the Transformer, and
> forced to ask it from manager and keep it on stack.
>
>
>> Bascially object != component.
>
> No objections. But heavy reusable object is a perfect candidate for a
> component (what are other distinguishable features of a
> object-to-be-component? Configuration?). That's why XMLSource can
> become component.
>

what is the best logical component here? The term "service" has come up in
this thread, and is a good term for its implications. Shoudl the
componenet be the Transformer or the XMLSource? It isn't "weight"
necessarily the specific main class that makes a good candidate for a
componenet, but the weight of the service it provides. I've had
services/componeents that themselves were almost no code - but provided a
solid, logical interface to a significant number of other classes. The
fact that XMLSource as an object is heavier than Transformer doesn't mean
it should be the component. If the two work together, and only one
componenet should exists, the real test is which logical compoenent
abstraction encompassing the two is more applicable  to the solution at
hand? (I'm not going to try to answer that by the way)
Keep in mind that I'm WAY behind on my understanding of Avalon - so feel
free to tell me where I'm wrong on any of this.
<snip/>
>>
>> The key here is being aware of the lifespan of the componenet you are
>> using. We used a default lifespan of a single request, but actually
> allow
>> you to "anchor" the compoenent to another object for its lifespan -
> when
>> that object went away, your component got cleanp-up/returned to the
> pool.
>
> I hope so. It was not clear from Berin's proposal.
>

Berin - did I understand correctly on this one? Or did I miss it too?

<snip/>

>> > Some transformers use instance of serializers to do its work. It
> could
>> > be looked up on startup and returned on shutdown (to speedup
> processing
>> > - right now manager.release() is quite expensive operation), and
> will
>> > not depend on request/response cycles.
>> >
>>
>> different componenets can have different basis for lifespans...it
> should
>> be done with caution and justification, but it doesn't break anything.
> It
>> is a container issue hwo and when it reclaims it. Pooling per request
> is
>> one lifetime appraoch a container could take.
>
> How container will know what should be the lifespan?
>

I done this many ways - componenet configration file, marker interfaces
and/or runtime capabilities discover of the class, and requestor specifed.
The first one has generally been the best since sometimes you have a
compoenent that is capable of being used globally, but you choose to
configure it at a smaller scope in a particualr case. The best system I've
worked with for this one had the ability to scope the life of a component
as request, session, user, application, or global at configuration time.
Within that scope it could then be pooled, created as needed, managed as a
singleton, etc. All transparent to the requesting object.

-- 
"The heights of genius are only measurable by the depths of stupidity."



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Andy Lewis <aj...@ascii27.net>.
<snip/>

>
> Yes, if they share same ... how you call it? ... scope: both are
> ThreadSafe or Poolable (by nature). Here, one (Transformer) will be
> ThreadSafe (or even not a component (it's too lightweight for it)), and
> other (XMLSource) - Poolable.
>
> Thus, you can not keep an instance of XMLSource in the Transformer, and
> forced to ask it from manager and keep it on stack.
>
>
>> Bascially object != component.
>
> No objections. But heavy reusable object is a perfect candidate for a
> component (what are other distinguishable features of a
> object-to-be-component? Configuration?). That's why XMLSource can
> become component.
>

what is the best logical component here? The term "service" has come up in
this thread, and is a good term for its implications. Shoudl the
componenet be the Transformer or the XMLSource? It isn't "weight"
necessarily the specific main class that makes a good candidate for a
componenet, but the weight of the service it provides. I've had
services/componeents that themselves were almost no code - but provided a
solid, logical interface to a significant number of other classes. The
fact that XMLSource as an object is heavier than Transformer doesn't mean
it should be the component. If the two work together, and only one
componenet should exists, the real test is which logical compoenent
abstraction encompassing the two is more applicable  to the solution at
hand? (I'm not going to try to answer that by the way)
Keep in mind that I'm WAY behind on my understanding of Avalon - so feel
free to tell me where I'm wrong on any of this.
<snip/>
>>
>> The key here is being aware of the lifespan of the componenet you are
>> using. We used a default lifespan of a single request, but actually
> allow
>> you to "anchor" the compoenent to another object for its lifespan -
> when
>> that object went away, your component got cleanp-up/returned to the
> pool.
>
> I hope so. It was not clear from Berin's proposal.
>

Berin - did I understand correctly on this one? Or did I miss it too?

<snip/>

>> > Some transformers use instance of serializers to do its work. It
> could
>> > be looked up on startup and returned on shutdown (to speedup
> processing
>> > - right now manager.release() is quite expensive operation), and
> will
>> > not depend on request/response cycles.
>> >
>>
>> different componenets can have different basis for lifespans...it
> should
>> be done with caution and justification, but it doesn't break anything.
> It
>> is a container issue hwo and when it reclaims it. Pooling per request
> is
>> one lifetime appraoch a container could take.
>
> How container will know what should be the lifespan?
>

I done this many ways - componenet configration file, marker interfaces
and/or runtime capabilities discover of the class, and requestor specifed.
The first one has generally been the best since sometimes you have a
compoenent that is capable of being used globally, but you choose to
configure it at a smaller scope in a particualr case. The best system I've
worked with for this one had the ability to scope the life of a component
as request, session, user, application, or global at configuration time.
Within that scope it could then be pooled, created as needed, managed as a
singleton, etc. All transparent to the requesting object.

-- 
"The heights of genius are only measurable by the depths of stupidity."



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Andy Lewis [mailto:ajl@ascii27.net]
> 
> <snip/>
> 
> >
> > If you to change Transformer interface to return only
> > XMLSource/ContentHandler, all the logic and state Transformer has
moves
> > into this XMLSource.
> >
> > Thus, XMLSource becomes heavy and Transformer light. Obviously,
> > Transformer becomes ThreadSafe (which is good) and XMLSource must be
> > made Poolable (its heavy, it is stateful).
> >
> > Instead of having one component we ended up with two. Please tell me
I
> > see things wrongly.
> >
> 
> actually - you end up with one compoent, but it may consist of more
than
> one object.

Yes, if they share same ... how you call it? ... scope: both are
ThreadSafe or Poolable (by nature). Here, one (Transformer) will be
ThreadSafe (or even not a component (it's too lightweight for it)), and
other (XMLSource) - Poolable.

Thus, you can not keep an instance of XMLSource in the Transformer, and
forced to ask it from manager and keep it on stack.


> Bascially object != component.

No objections. But heavy reusable object is a perfect candidate for a
component (what are other distinguishable features of a
object-to-be-component? Configuration?). That's why XMLSource can become
component.


> Only the transformer is a
> componenet. But components are conceptually large, and may as a result
> have any number of  other classes incolved in thier work.

Of course.


> I have
> implemented service frameworks in java before (though nothing the
level of
> comprehensiveness of Avalon) and this model works REALLY well.
> It is true that some componeents may have objects that they pool
though,
> depending on the implementation. WE create several abstracts to extend
for
> handling that when creating a component.
> <snip/>
> >
> > Two issues on this one:
> >
> <snip/>
> 
> The key here is being aware of the lifespan of the componenet you are
> using. We used a default lifespan of a single request, but actually
allow
> you to "anchor" the compoenent to another object for its lifespan -
when
> that object went away, your component got cleanp-up/returned to the
pool.

I hope so. It was not clear from Berin's proposal.


> <snip/>
> 
> >
> >> Anything that is more granular than that needs a
> >> different treatment.
> >
> > What could it be?
> >
> in some cases similar mechnisms will be used, but there is a
conceptual
> line her eon component vs. object. I'm on this thread because this is
an
> area where I feel like I have personally made A LOT of the possible
> mistakes on this path.
> <snip/>
> >
> > Some transformers use instance of serializers to do its work. It
could
> > be looked up on startup and returned on shutdown (to speedup
processing
> > - right now manager.release() is quite expensive operation), and
will
> > not depend on request/response cycles.
> >
> 
> different componenets can have different basis for lifespans...it
should
> be done with caution and justification, but it doesn't break anything.
It
> is a container issue hwo and when it reclaims it. Pooling per request
is
> one lifetime appraoch a container could take.

How container will know what should be the lifespan?

Vadim

> --
> "The heights of genius are only measurable by the depths of
stupidity."


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Andy Lewis [mailto:ajl@ascii27.net]
> 
> <snip/>
> 
> >
> > If you to change Transformer interface to return only
> > XMLSource/ContentHandler, all the logic and state Transformer has
moves
> > into this XMLSource.
> >
> > Thus, XMLSource becomes heavy and Transformer light. Obviously,
> > Transformer becomes ThreadSafe (which is good) and XMLSource must be
> > made Poolable (its heavy, it is stateful).
> >
> > Instead of having one component we ended up with two. Please tell me
I
> > see things wrongly.
> >
> 
> actually - you end up with one compoent, but it may consist of more
than
> one object.

Yes, if they share same ... how you call it? ... scope: both are
ThreadSafe or Poolable (by nature). Here, one (Transformer) will be
ThreadSafe (or even not a component (it's too lightweight for it)), and
other (XMLSource) - Poolable.

Thus, you can not keep an instance of XMLSource in the Transformer, and
forced to ask it from manager and keep it on stack.


> Bascially object != component.

No objections. But heavy reusable object is a perfect candidate for a
component (what are other distinguishable features of a
object-to-be-component? Configuration?). That's why XMLSource can become
component.


> Only the transformer is a
> componenet. But components are conceptually large, and may as a result
> have any number of  other classes incolved in thier work.

Of course.


> I have
> implemented service frameworks in java before (though nothing the
level of
> comprehensiveness of Avalon) and this model works REALLY well.
> It is true that some componeents may have objects that they pool
though,
> depending on the implementation. WE create several abstracts to extend
for
> handling that when creating a component.
> <snip/>
> >
> > Two issues on this one:
> >
> <snip/>
> 
> The key here is being aware of the lifespan of the componenet you are
> using. We used a default lifespan of a single request, but actually
allow
> you to "anchor" the compoenent to another object for its lifespan -
when
> that object went away, your component got cleanp-up/returned to the
pool.

I hope so. It was not clear from Berin's proposal.


> <snip/>
> 
> >
> >> Anything that is more granular than that needs a
> >> different treatment.
> >
> > What could it be?
> >
> in some cases similar mechnisms will be used, but there is a
conceptual
> line her eon component vs. object. I'm on this thread because this is
an
> area where I feel like I have personally made A LOT of the possible
> mistakes on this path.
> <snip/>
> >
> > Some transformers use instance of serializers to do its work. It
could
> > be looked up on startup and returned on shutdown (to speedup
processing
> > - right now manager.release() is quite expensive operation), and
will
> > not depend on request/response cycles.
> >
> 
> different componenets can have different basis for lifespans...it
should
> be done with caution and justification, but it doesn't break anything.
It
> is a container issue hwo and when it reclaims it. Pooling per request
is
> one lifetime appraoch a container could take.

How container will know what should be the lifespan?

Vadim

> --
> "The heights of genius are only measurable by the depths of
stupidity."


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Andy Lewis <aj...@ascii27.net>.
<snip/>

>
> If you to change Transformer interface to return only
> XMLSource/ContentHandler, all the logic and state Transformer has moves
> into this XMLSource.
>
> Thus, XMLSource becomes heavy and Transformer light. Obviously,
> Transformer becomes ThreadSafe (which is good) and XMLSource must be
> made Poolable (its heavy, it is stateful).
>
> Instead of having one component we ended up with two. Please tell me I
> see things wrongly.
>

actually - you end up with one compoent, but it may consist of more than
one object. Bascially object != component. Only the transformer is a
componenet. But components are conceptually large, and may as a result
have any number of  other classes incolved in thier work. I have
implemented service frameworks in java before (though nothing the level of
comprehensiveness of Avalon) and this model works REALLY well.
It is true that some componeents may have objects that they pool though,
depending on the implementation. WE create several abstracts to extend for
handling that when creating a component.
<snip/>
>
> Two issues on this one:
>
<snip/>

The key here is being aware of the lifespan of the componenet you are
using. We used a default lifespan of a single request, but actually allow
you to "anchor" the compoenent to another object for its lifespan - when
that object went away, your component got cleanp-up/returned to the pool.
<snip/>

>
>> Anything that is more granular than that needs a
>> different treatment.
>
> What could it be?
>
in some cases similar mechnisms will be used, but there is a conceptual
line her eon component vs. object. I'm on this thread because this is an
area where I feel like I have personally made A LOT of the possible
mistakes on this path.
<snip/>
>
> Some transformers use instance of serializers to do its work. It could
> be looked up on startup and returned on shutdown (to speedup processing
> - right now manager.release() is quite expensive operation), and will
> not depend on request/response cycles.
>

different componenets can have different basis for lifespans...it should
be done with caution and justification, but it doesn't break anything. It
is a container issue hwo and when it reclaims it. Pooling per request is
one lifetime appraoch a container could take.
-- 
"The heights of genius are only measurable by the depths of stupidity."



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Gregory Steuck <gr...@nest.cx>.
>>>>> "Leo" == Leo Sutic <le...@inspireinfrastructure.com> writes:

    Leo> The difference is this - with explicit release I can:
  
    Leo>    public void someMethod () { component = manager.lookup
    Leo> (ExpensiveButPooledComponent.ROLE); ...  manager.release
    Leo> (component); <<<<<<<<<<<< Added this }

    Leo> And thus not drain the pool, as I only really need 1
    Leo> instance.

    Leo> As for whether this is efficient or not - that is not the
    Leo> issue. 

Wouldn't it be more IoCish to pass an instance of
ExpensiveButPooledComponent to the method as opposed to it acquiring
such instance on it's own?

    Leo> The point is that with a per-request GC, you will
    Leo> need to lookup all components you require *at the start of
    Leo> the request* and then pass those around as you process the
    Leo> request (to avoid too many lookups) - unless you are really
    Leo> sure that you will not end up in a situation similar to the
    Leo> one I described. (That is, you repeatedly call a method that
    Leo> does a lookup during a single request. It will never be as
    Leo> simple as the example: someMethod() will call someOtherMethod
    Leo> and so on until, 20 steps up the call stack, you have a
    Leo> lookup. And then, 20 more steps until the last method
    Leo> returns.)

If I am not mistaken you just described a component with PerThread
lifestyle policy, no?

Another alternative is you build an object along the lines:

class SomeMethodDoer {
   SomeMethodDoer(ExpensiveButPooledComponent) {
   } 

   someMethod() {
   }
}

And then build it (yes, explicit new) and call someMethod as many
times as you need.

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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Gregory Steuck <gr...@nest.cx>.
>>>>> "Leo" == Leo Sutic <le...@inspireinfrastructure.com> writes:

    Leo> The difference is this - with explicit release I can:
  
    Leo>    public void someMethod () { component = manager.lookup
    Leo> (ExpensiveButPooledComponent.ROLE); ...  manager.release
    Leo> (component); <<<<<<<<<<<< Added this }

    Leo> And thus not drain the pool, as I only really need 1
    Leo> instance.

    Leo> As for whether this is efficient or not - that is not the
    Leo> issue. 

Wouldn't it be more IoCish to pass an instance of
ExpensiveButPooledComponent to the method as opposed to it acquiring
such instance on it's own?

    Leo> The point is that with a per-request GC, you will
    Leo> need to lookup all components you require *at the start of
    Leo> the request* and then pass those around as you process the
    Leo> request (to avoid too many lookups) - unless you are really
    Leo> sure that you will not end up in a situation similar to the
    Leo> one I described. (That is, you repeatedly call a method that
    Leo> does a lookup during a single request. It will never be as
    Leo> simple as the example: someMethod() will call someOtherMethod
    Leo> and so on until, 20 steps up the call stack, you have a
    Leo> lookup. And then, 20 more steps until the last method
    Leo> returns.)

If I am not mistaken you just described a component with PerThread
lifestyle policy, no?

Another alternative is you build an object along the lines:

class SomeMethodDoer {
   SomeMethodDoer(ExpensiveButPooledComponent) {
   } 

   someMethod() {
   }
}

And then build it (yes, explicit new) and call someMethod as many
times as you need.

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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Andy Lewis <aj...@ascii27.net>.
<snip/>

>
> If you to change Transformer interface to return only
> XMLSource/ContentHandler, all the logic and state Transformer has moves
> into this XMLSource.
>
> Thus, XMLSource becomes heavy and Transformer light. Obviously,
> Transformer becomes ThreadSafe (which is good) and XMLSource must be
> made Poolable (its heavy, it is stateful).
>
> Instead of having one component we ended up with two. Please tell me I
> see things wrongly.
>

actually - you end up with one compoent, but it may consist of more than
one object. Bascially object != component. Only the transformer is a
componenet. But components are conceptually large, and may as a result
have any number of  other classes incolved in thier work. I have
implemented service frameworks in java before (though nothing the level of
comprehensiveness of Avalon) and this model works REALLY well.
It is true that some componeents may have objects that they pool though,
depending on the implementation. WE create several abstracts to extend for
handling that when creating a component.
<snip/>
>
> Two issues on this one:
>
<snip/>

The key here is being aware of the lifespan of the componenet you are
using. We used a default lifespan of a single request, but actually allow
you to "anchor" the compoenent to another object for its lifespan - when
that object went away, your component got cleanp-up/returned to the pool.
<snip/>

>
>> Anything that is more granular than that needs a
>> different treatment.
>
> What could it be?
>
in some cases similar mechnisms will be used, but there is a conceptual
line her eon component vs. object. I'm on this thread because this is an
area where I feel like I have personally made A LOT of the possible
mistakes on this path.
<snip/>
>
> Some transformers use instance of serializers to do its work. It could
> be looked up on startup and returned on shutdown (to speedup processing
> - right now manager.release() is quite expensive operation), and will
> not depend on request/response cycles.
>

different componenets can have different basis for lifespans...it should
be done with caution and justification, but it doesn't break anything. It
is a container issue hwo and when it reclaims it. Pooling per request is
one lifetime appraoch a container could take.
-- 
"The heights of genius are only measurable by the depths of stupidity."



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Andy Lewis <aj...@ascii27.net>.
I've always maintained that the key difference between an object and a
component is granularity. Both can be reusable, but a component generally
represents a (reusable)  encapsulation of a conceptually larger "chunk" of
logic/data than a typical object.

>> From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
>>
>> > From: Berin Loritsch [mailto:bloritsch@apache.org]
>> >
>> > > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
>> > >
>> > > Suppose you have a pool-max of 3:
>> > >
>> > >    public void handleRequest () {
>> > >       someMethod ();
>> > >       someMethod ();
>> > >       someMethod ();
>> > >       someMethod ();
>> > >    }
>> >
>> > And this is different from the current state of affairs, how?
>> > If a request requires 5 transformer instances, and you have
>> > your pool max set to 3, you will still experience slow down.   This
>> > is no different than automatically releasing a component  when the
>> > request is handled.
>>
>> The difference is this - with explicit release I can:
>>
>>    public void someMethod () {
>>       component = manager.lookup (ExpensiveButPooledComponent.ROLE);
>>       ...
>>        manager.release (component); <<<<<<<<<<<< Added this
>>    }
>>
>> And thus not drain the pool, as I only really need 1 instance.
>>
>> As for whether this is efficient or not - that is not the
>> issue. The point is that with a per-request GC, you will need
>> to lookup all components you require *at the start of the
>> request* and then pass those around as you process the
>> request (to avoid too many lookups) -
>> unless you  are really sure that you will not end up in a situation
>> similar to the one I described. (That is, you repeatedly call
>> a method that does a lookup during a single request. It will never be
>> as simple as the example: someMethod() will call someOtherMethod and
>> so on until, 20 steps up the call stack, you have a lookup.
>> And then, 20 more steps until the last method returns.)
>
> Hmm.  What we have here is a bad design.  Should the container
> make up for your poor design?  Can you really get away with only
> three instances in a pool with a web environment?  Honestly,
> there is nothing in Cocoon that does what you are talking about.
>
> You have something more than "I may want to implement this poor
> design some day" that we can discuss?
>
> What you described here is woefully innefficient, and you will
> have to refactor it completely in the very near future.  Why not
> discourage bad design?
>
>
>> > I am finding more and more what people are calling components
>> > are nothing more than Objects that observe the Bridge
>> > pattern.  They implement an interface, introduce a few
>> > lifecycle methods, etc. If they are object then they should
>> > be treated as such.
>>
>> Then what is a component? A Facade?
>
> A component is a reusable binary that observes a public interface. All
> component implementations of a specific public interface are
> interchangeable.  The Bridge pattern states that the implementation
> observes an external interface--you can't have components without
> that.
>
> However, the most successful components "do", not "represent".
> It's a conceptual thing.  If you process a request by calling a
> method on a component, then we are all good.  If you have a component
> represent something and call multiple method calls on it, then
> we run into the problems we are experiencing.
>
> Now, a way to philisophically enforce the "do" vs. "represent"
> concept is to call the components by a new name: services.  A service
> is a type of component that "does" something or performs a service.
>
>
>> > If a pooled object requires an explicit
>> > return to a pool, than that decision should be made in the
>> > GeneratorManager, or the TransformerManager, etc.  Not in the  core
>> > lookup mechanism.
>>
>> What you propose is then that pooling is removed from
>> the container itself. Pooling will be done by first using a
>> component manager to lookup another manager, and then use
>> that manager to obtain an instance from the pool. Am I correct?
>
> That is one way of handling what you are talking about without
> writing a GC routine.
>
>
>> > >      ...means a load of GC policy parameters for the client.
>> >
>> > ? I don't get this at all.
>>
>> I meant "user", not "client". My bad.
>
> It's still a container concern.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
> For additional commands, email: cocoon-dev-help@xml.apache.org


-- 
"The heights of genius are only measurable by the depths of stupidity."



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Berin Loritsch [mailto:bloritsch@apache.org]
> 
> > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> >
> > > From: Berin Loritsch [mailto:bloritsch@apache.org]
> > >
> > > Hmm.  What we have here is a bad design.  Should the
> > > container make up for your poor design?  Can you really get
> > > away with only three instances in a pool with a web
> > > environment?  Honestly, there is nothing in Cocoon that does
> > > what you are talking about.
> >
> > Yes, it is bad design. It is more than that - it is horrible design.
> >
> > But admit one thing: It was not difficult to see that it was
> > utterly atrocious!
> >
> > I meant to use it to show a situation that may occur in a
> > system. It will not be as clearly awful as the abomination I
> > showed you, but *hidden* in the code. I can show you more
> > poor architecture:
> >
> >   public void tailRecursive (int i) {
> >     if (i < 100) {
> >       mycomp = lookup (...);
> >       tailRecursive (i + 1);
> >     }
> >   }
> 
> In order for a component based system to gain all benefits of being
> component based, we have to consider the "story" of the system.  After
> all, that is where we develop our roles.  From the story that we are
> trying to tell.
> 
> The point is that you should know ahead of time, what the correct
> story is.  You should know how, in a certain context the components
> relate to each other.  That is what design is all about.  As much as
> possible, you should strive to make your components as threadsafe
> as possible.  That way you just don't have to worry about certain
> things.
> 
> Systemic problems such as your recursive and iterative lookups should
> not be allowed by design. 

What's wrong with this:

public void do () {
  for (int I = 0; i < 8000; i++) {
    mycomp = lookup (...);
    info = mycomp.getIt(i);
    release(mycomp);

    info = calculate(info);
    print(info);
  }
}

Assumptions: mycomp.getIt() might use JDBC connection which are limited
in count, and calculate() takes some time, so it is really not wise to
block connection for time of the whole loop.


Vadim 

</snip>



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com] 
> 
> > From: Berin Loritsch [mailto:bloritsch@apache.org]
> > 
> > > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > > 
> > > > From: Berin Loritsch [mailto:bloritsch@apache.org]
> > > > 
> > > > > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > > > > 
> >
> > Hmm.  What we have here is a bad design.  Should the
> > container make up for your poor design?  Can you really get 
> > away with only three instances in a pool with a web 
> > environment?  Honestly, there is nothing in Cocoon that does 
> > what you are talking about.
> 
> Yes, it is bad design. It is more than that - it is horrible design.
> 
> But admit one thing: It was not difficult to see that it was 
> utterly atrocious!
> 
> I meant to use it to show a situation that may occur in a 
> system. It will not be as clearly awful as the abomination I 
> showed you, but *hidden* in the code. I can show you more 
> poor architecture:
> 
>   public void tailRecursive (int i) {
>     if (i < 100) {
>       mycomp = lookup (...);
>       tailRecursive (i + 1);
>     }
>   }

In order for a component based system to gain all benefits of being
component based, we have to consider the "story" of the system.  After
all, that is where we develop our roles.  From the story that we are
trying to tell.

The point is that you should know ahead of time, what the correct
story is.  You should know how, in a certain context the components
relate to each other.  That is what design is all about.  As much as
possible, you should strive to make your components as threadsafe
as possible.  That way you just don't have to worry about certain
things.

Systemic problems such as your recursive and iterative lookups should
not be allowed by design.  But (in the imortal words of Smokey the Bear)
"Only you can prevent forest fires."  Let's take, for example, the
Sitemap.  We have the ability to mount child sitemaps.  Each child
sitemap has a set of components it can access.  If all the components
specified in the parent sitemap are sufficient, then the child sitmap
uses the parent's versions.

Let's say we have our request answered by the seventh deep sitemap.
So far, all we have done is used Matchers and Selectors, and possibly
some Actions which have traditionally been forced to be ThreadSafe.
Theorhitically, if all the Matchers and Selectors are threadsafe,
then they only need to be requested once.  I.e. they are resolved
at sitemap initialization and held indefinitely.  I personally think
that a Matcher/Selector is too low a granularity to use for a component.
Nevertheless, we finally arrive at our entry in the seventh deep
sitemap.  This happens to be an aggregation of two sources, each
having some transformation done to them, and finally we transform
the final result and serialize it.  So our pipeline looks like this:

G->T->T
       \
        *->T->S
       /
G->T->T

In essence we have a three pipelines, with one being the merging of
two of them.  We can either view our Aggregator as a special generator,
or we can view it as a special transformer.  It is closer to a
transformer
that accepts multiple inputs than anything else.  Currently there is
no notion of an Aggregator COMPONENT, it is merely a function of the
sitemap (why didn't we do that with Selectors/Matchers?).

So far we will have a total of two generators, five transformers, and
one serializer.  Since a request is handled linearly, we can potentially
optimize it so that we are only using one generator and three
transformers
at any one time.  A smart aggregator would only handle events from the
input pipeline, kill it, and then process events from the next pipeline.

In this case, if we had a recursion in the pipeline, we would likely
see it as an infinite loop.  Such a thing is *really bad*, and the
developer
will detect it almost immediately.  If a developer wants a self
recurring
pipeline that handled different pieces with a matcher/selector to handle
logic, we have effectively jerked off with our core design.  If you need
that type of dynamic logic control, then you need a different tool.

Now, there is no reason to repeatedly apply the same transformer to a
pipeline either (unless you are a glutton for punishment).

So I am having a hard time seeing in real life where your systemic
problems would occur.

Using the pipeline model, no generator, transformer, or serializer has
any real business directly interacting with each other.  Those are
functions
of the container--the sitemap.  Therefore, the sitemap should exert the
proper control over its components.  The pipeline should work with
XMLSource
and ContentHandlers directly--releiving the critical path of repeated
lookups.

Also keep in mind that with GC based systems, we have to accept that we
may be using more memory than we would otherwise have to use if we
manually
managed memmory.

> 


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com] 
> 
> > From: Berin Loritsch [mailto:bloritsch@apache.org]
> > 
> > > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > > 
> > > > From: Berin Loritsch [mailto:bloritsch@apache.org]
> > > > 
> > > > > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > > > > 
> >
> > Hmm.  What we have here is a bad design.  Should the
> > container make up for your poor design?  Can you really get 
> > away with only three instances in a pool with a web 
> > environment?  Honestly, there is nothing in Cocoon that does 
> > what you are talking about.
> 
> Yes, it is bad design. It is more than that - it is horrible design.
> 
> But admit one thing: It was not difficult to see that it was 
> utterly atrocious!
> 
> I meant to use it to show a situation that may occur in a 
> system. It will not be as clearly awful as the abomination I 
> showed you, but *hidden* in the code. I can show you more 
> poor architecture:
> 
>   public void tailRecursive (int i) {
>     if (i < 100) {
>       mycomp = lookup (...);
>       tailRecursive (i + 1);
>     }
>   }

In order for a component based system to gain all benefits of being
component based, we have to consider the "story" of the system.  After
all, that is where we develop our roles.  From the story that we are
trying to tell.

The point is that you should know ahead of time, what the correct
story is.  You should know how, in a certain context the components
relate to each other.  That is what design is all about.  As much as
possible, you should strive to make your components as threadsafe
as possible.  That way you just don't have to worry about certain
things.

Systemic problems such as your recursive and iterative lookups should
not be allowed by design.  But (in the imortal words of Smokey the Bear)
"Only you can prevent forest fires."  Let's take, for example, the
Sitemap.  We have the ability to mount child sitemaps.  Each child
sitemap has a set of components it can access.  If all the components
specified in the parent sitemap are sufficient, then the child sitmap
uses the parent's versions.

Let's say we have our request answered by the seventh deep sitemap.
So far, all we have done is used Matchers and Selectors, and possibly
some Actions which have traditionally been forced to be ThreadSafe.
Theorhitically, if all the Matchers and Selectors are threadsafe,
then they only need to be requested once.  I.e. they are resolved
at sitemap initialization and held indefinitely.  I personally think
that a Matcher/Selector is too low a granularity to use for a component.
Nevertheless, we finally arrive at our entry in the seventh deep
sitemap.  This happens to be an aggregation of two sources, each
having some transformation done to them, and finally we transform
the final result and serialize it.  So our pipeline looks like this:

G->T->T
       \
        *->T->S
       /
G->T->T

In essence we have a three pipelines, with one being the merging of
two of them.  We can either view our Aggregator as a special generator,
or we can view it as a special transformer.  It is closer to a
transformer
that accepts multiple inputs than anything else.  Currently there is
no notion of an Aggregator COMPONENT, it is merely a function of the
sitemap (why didn't we do that with Selectors/Matchers?).

So far we will have a total of two generators, five transformers, and
one serializer.  Since a request is handled linearly, we can potentially
optimize it so that we are only using one generator and three
transformers
at any one time.  A smart aggregator would only handle events from the
input pipeline, kill it, and then process events from the next pipeline.

In this case, if we had a recursion in the pipeline, we would likely
see it as an infinite loop.  Such a thing is *really bad*, and the
developer
will detect it almost immediately.  If a developer wants a self
recurring
pipeline that handled different pieces with a matcher/selector to handle
logic, we have effectively jerked off with our core design.  If you need
that type of dynamic logic control, then you need a different tool.

Now, there is no reason to repeatedly apply the same transformer to a
pipeline either (unless you are a glutton for punishment).

So I am having a hard time seeing in real life where your systemic
problems would occur.

Using the pipeline model, no generator, transformer, or serializer has
any real business directly interacting with each other.  Those are
functions
of the container--the sitemap.  Therefore, the sitemap should exert the
proper control over its components.  The pipeline should work with
XMLSource
and ContentHandlers directly--releiving the critical path of repeated
lookups.

Also keep in mind that with GC based systems, we have to accept that we
may be using more memory than we would otherwise have to use if we
manually
managed memmory.

> 


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Vadim Gritsenko [mailto:vadim.gritsenko@verizon.net] 
> 
> JDBC connection must be aware of pooling (special handling in the
> close() method), which does not look good - current Avalon 
> model where poolable component must not care about how it is 
> being pooled is *much* better.

The connection itself is not aware of it.  In fact you can use just
about any vendor's JDBC driver with the same DataSourceComponent.
The DataSourceComponent wraps the JDBC driver with a proxy--just like
the DataSource spec says.  It's not that difficult to do.


> > I am advocating the same thing for the CM
> 
> Do you propose to make pooling concern of the component? 
> (I.e., manual pooling as in JDBC?)


I am for supporting components up the the Per-Thread request model,
and anything that needs a Per-Lookup request model needs to be
redesigned.  This allows the container to be smart about the instances.
It can either use ThreadLocals to create the Components (too slow
on JDK 1.2 and before), or a finite number of components to share
between the threads.  The number of component instances really shouldn't
exceed the number of threads.

Consider Cocoon.

The Transformer is a Per-Lookup design.  This is too limiting.  Let's
assume we have a pipeline with 5 transformers.  That means the pool
for the transformer must be 5*Tn where Tn is the number of threads.
Even if we cut this to 70% of the value, Servlet engines can have
anywhere between 20 to 100 threads handling incoming requests.  So
we are talking at least 70 components and at most 500 used at any
one time.

Worse, certain optimizations on the usage of the artifacts become much
more difficult to assemble.  Certain things like caching mechanisms have
to be worked into the scheme of things across multiple component
instances
as opposed to each component type.  Furthermore, you cannot directly
substitute a cached resource for the original.

With the current state of affairs, it is very difficult to understand
why Cocoon uses 50-60 MB of RAM for even the simplest of systems.
Overpooling is an antipattern just as underpooling is.  We need to use
more judicious pooling mechanisms--ones that are smarter.  I highly
recommend looking at Fortress in Excalibur for a better pool mechanism.

Fortress can do everything ECM can do, and do it quicker and faster,
with self discovering pools sizes.  I highly recommend it.  Things like
releasing the components no longer slow down the critical path of
processing requests.  It is faster to start up, faster to use, but
slower
to completely shut down.  That's OK, because Cocoon can use a quicker
startup time and could stand to process requests even faster.

In low simultaneous thread counts such as 10 to 15 threads, there isn't
a lot of difference between ECM and Fortress in the time it takes to
lookup and release components.  However, under high load with upwards
of 100 threads or more, Fortress kills ECM in performance by a factor
of 16 (and in some cases even more).  The main reason is the gentler
saturation curve because of asynchronous releasing of components.

In a world where we did not need to release components explicitly, we
would see even better improvements.

The higher abstraction that I advocate actually helps organize thoughts
and enable the easier integration of optimization possibilities.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Vadim Gritsenko [mailto:vadim.gritsenko@verizon.net] 
> 
> JDBC connection must be aware of pooling (special handling in the
> close() method), which does not look good - current Avalon 
> model where poolable component must not care about how it is 
> being pooled is *much* better.

The connection itself is not aware of it.  In fact you can use just
about any vendor's JDBC driver with the same DataSourceComponent.
The DataSourceComponent wraps the JDBC driver with a proxy--just like
the DataSource spec says.  It's not that difficult to do.


> > I am advocating the same thing for the CM
> 
> Do you propose to make pooling concern of the component? 
> (I.e., manual pooling as in JDBC?)


I am for supporting components up the the Per-Thread request model,
and anything that needs a Per-Lookup request model needs to be
redesigned.  This allows the container to be smart about the instances.
It can either use ThreadLocals to create the Components (too slow
on JDK 1.2 and before), or a finite number of components to share
between the threads.  The number of component instances really shouldn't
exceed the number of threads.

Consider Cocoon.

The Transformer is a Per-Lookup design.  This is too limiting.  Let's
assume we have a pipeline with 5 transformers.  That means the pool
for the transformer must be 5*Tn where Tn is the number of threads.
Even if we cut this to 70% of the value, Servlet engines can have
anywhere between 20 to 100 threads handling incoming requests.  So
we are talking at least 70 components and at most 500 used at any
one time.

Worse, certain optimizations on the usage of the artifacts become much
more difficult to assemble.  Certain things like caching mechanisms have
to be worked into the scheme of things across multiple component
instances
as opposed to each component type.  Furthermore, you cannot directly
substitute a cached resource for the original.

With the current state of affairs, it is very difficult to understand
why Cocoon uses 50-60 MB of RAM for even the simplest of systems.
Overpooling is an antipattern just as underpooling is.  We need to use
more judicious pooling mechanisms--ones that are smarter.  I highly
recommend looking at Fortress in Excalibur for a better pool mechanism.

Fortress can do everything ECM can do, and do it quicker and faster,
with self discovering pools sizes.  I highly recommend it.  Things like
releasing the components no longer slow down the critical path of
processing requests.  It is faster to start up, faster to use, but
slower
to completely shut down.  That's OK, because Cocoon can use a quicker
startup time and could stand to process requests even faster.

In low simultaneous thread counts such as 10 to 15 threads, there isn't
a lot of difference between ECM and Fortress in the time it takes to
lookup and release components.  However, under high load with upwards
of 100 threads or more, Fortress kills ECM in performance by a factor
of 16 (and in some cases even more).  The main reason is the gentler
saturation curve because of asynchronous releasing of components.

In a world where we did not need to release components explicitly, we
would see even better improvements.

The higher abstraction that I advocate actually helps organize thoughts
and enable the easier integration of optimization possibilities.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Berin Loritsch [mailto:bloritsch@apache.org]
> 
> > From: Vadim Gritsenko [mailto:vadim.gritsenko@verizon.net]
> >
> > In J2EE, it is common to have session EJBs working with JDBC
> > connection. You obtain connection whenever you need it and
> > return to the pool when you are done.
> 
> Semantic clarification:
> 
> You get the DataSource, and call getConnection().  The DataSource
> may have pooled the connection or not.  That's not really the
> point.  You never explicitly return it to a pool.  You call
> connection.close(), and if the connection is pooled then it is
> silently returned to the pool.
> 
> That is a key distinction.

Ok, I used wrong name here, replace JDBC Connection with
SomeLegacyLimitedResourceComponent for this discussion, limited in count
and critical for application, and thus must not be held for too long
time.


> You LOOKUP the DataSource, which can be shared between all threads,
> and then you USE it to get the connection INSTANCE.  The instance
> is used the same way WHETHER IT IS POOLED OR NOT.

JDBC connection must be aware of pooling (special handling in the
close() method), which does not look good - current Avalon model where
poolable component must not care about how it is being pooled is *much*
better.

 
> I am advocating the same thing for the CM

Do you propose to make pooling concern of the component? (I.e., manual
pooling as in JDBC?)

Vadim



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Vadim Gritsenko [mailto:vadim.gritsenko@verizon.net] 
> 
> In J2EE, it is common to have session EJBs working with JDBC 
> connection. You obtain connection whenever you need it and 
> return to the pool when you are done.

Semantic clarification:

You get the DataSource, and call getConnection().  The DataSource
may have pooled the connection or not.  That's not really the
point.  You never explicitly return it to a pool.  You call
connection.close(), and if the connection is pooled then it is
silently returned to the pool.

That is a key distinction.

You LOOKUP the DataSource, which can be shared between all threads,
and then you USE it to get the connection INSTANCE.  The instance
is used the same way WHETHER IT IS POOLED OR NOT.

I am advocating the same thing for the CM


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> 
> > From: Berin Loritsch [mailto:bloritsch@apache.org]
> >
> > Hmm.  What we have here is a bad design.  Should the
> > container make up for your poor design?  Can you really get
> > away with only three instances in a pool with a web
> > environment?  Honestly, there is nothing in Cocoon that does
> > what you are talking about.
> 
> Yes, it is bad design. It is more than that - it is horrible design.
> 
> But admit one thing: It was not difficult to see that it was
> utterly atrocious!
> 
> I meant to use it to show a situation that may occur in a system. It
> will
> not be as clearly awful as the abomination I showed you, but *hidden*
> in the code. I can show you more poor architecture:
> 
>   public void tailRecursive (int i) {
>     if (i < 100) {
>       mycomp = lookup (...);
>       tailRecursive (i + 1);
>     }
>   }
> 
> Of course, the component should be passed in to the method. The point
is
> that you may have these patterns in your system on a much larger scale
> *without knowing* it.

I do not (fully) agree with you here.

In J2EE, it is common to have session EJBs working with JDBC connection.
You obtain connection whenever you need it and return to the pool when
you are done.

If you to write Avalon application after this pattern, you will have
several ThreadSafe components (session EJB) and one or more pools of
JDBC connections. Every component's responsibility will be to lookup and
return connection.

What you are proposing is to pass this connection across all these
components, and move the responsibility of connection management from
component which uses it to the caller who might not be aware about it at
all - and it should not, because caller does not need to know
component's dependencies.

Moreover, if component needs more then one component to work (and this
is not the rare case), or different components need different
connections/other components, you will end up with lots of arguments in
every business interface (or Map filled with required components... why
not just pass manager as an argument?)


> You will suddenly experience massive slowdowns and not know what is
> happening. After a few hours or days of going through code you realize
> that
> a certain method is being called multiple times. And that method does
a
> lookup.
> 
> > You have something more than "I may want to implement this
> > poor design some day" that we can discuss?
> 
> As I said above, I tried to show you a pattern by distilling it
> to a very short example. Apparently I failed so badly that you
> thought I really advocated writing of such code.
> 
> > Why not discourage bad design?
> 
> Why not? Well, it depends on how that discouragement is done.
> If designing your component poorly leads to YourCodeSucksErrors being
> thrown all over the place (with correct line number and file info) the
> moment you start the server, then I'm all for it.
> 
> But if, when you do something that is completely correct within the
> context of your component, but, in interaction with other parts of the
> system that you may not know of, leads to sporadic and erratic
behaviour
> seemingly unrelated to your code - then that discouragement is not
> helping anyone.

I completely agree with this point. This will make it very difficult to
write reusable components, and impossible to envision behavior of
complex system.

Vadim


> > Now, a way to philisophically enforce the "do" vs.
> > "represent" concept is to call the components by a new name:
> > services.  A service is a type of component that "does"
> > something or performs a service.
> 
> OK, got it.
> 
> I disagree, but that is for another time.
> 
> /LS



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> 
> > From: Berin Loritsch [mailto:bloritsch@apache.org]
> >
> > Hmm.  What we have here is a bad design.  Should the
> > container make up for your poor design?  Can you really get
> > away with only three instances in a pool with a web
> > environment?  Honestly, there is nothing in Cocoon that does
> > what you are talking about.
> 
> Yes, it is bad design. It is more than that - it is horrible design.
> 
> But admit one thing: It was not difficult to see that it was
> utterly atrocious!
> 
> I meant to use it to show a situation that may occur in a system. It
> will
> not be as clearly awful as the abomination I showed you, but *hidden*
> in the code. I can show you more poor architecture:
> 
>   public void tailRecursive (int i) {
>     if (i < 100) {
>       mycomp = lookup (...);
>       tailRecursive (i + 1);
>     }
>   }
> 
> Of course, the component should be passed in to the method. The point
is
> that you may have these patterns in your system on a much larger scale
> *without knowing* it.

I do not (fully) agree with you here.

In J2EE, it is common to have session EJBs working with JDBC connection.
You obtain connection whenever you need it and return to the pool when
you are done.

If you to write Avalon application after this pattern, you will have
several ThreadSafe components (session EJB) and one or more pools of
JDBC connections. Every component's responsibility will be to lookup and
return connection.

What you are proposing is to pass this connection across all these
components, and move the responsibility of connection management from
component which uses it to the caller who might not be aware about it at
all - and it should not, because caller does not need to know
component's dependencies.

Moreover, if component needs more then one component to work (and this
is not the rare case), or different components need different
connections/other components, you will end up with lots of arguments in
every business interface (or Map filled with required components... why
not just pass manager as an argument?)


> You will suddenly experience massive slowdowns and not know what is
> happening. After a few hours or days of going through code you realize
> that
> a certain method is being called multiple times. And that method does
a
> lookup.
> 
> > You have something more than "I may want to implement this
> > poor design some day" that we can discuss?
> 
> As I said above, I tried to show you a pattern by distilling it
> to a very short example. Apparently I failed so badly that you
> thought I really advocated writing of such code.
> 
> > Why not discourage bad design?
> 
> Why not? Well, it depends on how that discouragement is done.
> If designing your component poorly leads to YourCodeSucksErrors being
> thrown all over the place (with correct line number and file info) the
> moment you start the server, then I'm all for it.
> 
> But if, when you do something that is completely correct within the
> context of your component, but, in interaction with other parts of the
> system that you may not know of, leads to sporadic and erratic
behaviour
> seemingly unrelated to your code - then that discouragement is not
> helping anyone.

I completely agree with this point. This will make it very difficult to
write reusable components, and impossible to envision behavior of
complex system.

Vadim


> > Now, a way to philisophically enforce the "do" vs.
> > "represent" concept is to call the components by a new name:
> > services.  A service is a type of component that "does"
> > something or performs a service.
> 
> OK, got it.
> 
> I disagree, but that is for another time.
> 
> /LS



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Leo Sutic <le...@inspireinfrastructure.com>.
> From: Berin Loritsch [mailto:bloritsch@apache.org] 
> 
> > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > 
> > > From: Berin Loritsch [mailto:bloritsch@apache.org]
> > > 
> > > > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > > > 
>
> Hmm.  What we have here is a bad design.  Should the 
> container make up for your poor design?  Can you really get 
> away with only three instances in a pool with a web 
> environment?  Honestly, there is nothing in Cocoon that does 
> what you are talking about.

Yes, it is bad design. It is more than that - it is horrible design.

But admit one thing: It was not difficult to see that it was 
utterly atrocious!

I meant to use it to show a situation that may occur in a system. It
will
not be as clearly awful as the abomination I showed you, but *hidden*
in the code. I can show you more poor architecture:

  public void tailRecursive (int i) {
    if (i < 100) {
      mycomp = lookup (...);
      tailRecursive (i + 1);
    }
  }

Of course, the component should be passed in to the method. The point is
that you may have these patterns in your system on a much larger scale
*without knowing* it.

You will suddenly experience massive slowdowns and not know what is 
happening. After a few hours or days of going through code you realize
that
a certain method is being called multiple times. And that method does a 
lookup.
 
> You have something more than "I may want to implement this 
> poor design some day" that we can discuss?

As I said above, I tried to show you a pattern by distilling it
to a very short example. Apparently I failed so badly that you
thought I really advocated writing of such code.

> Why not discourage bad design?

Why not? Well, it depends on how that discouragement is done.
If designing your component poorly leads to YourCodeSucksErrors being
thrown all over the place (with correct line number and file info) the 
moment you start the server, then I'm all for it. 

But if, when you do something that is completely correct within the 
context of your component, but, in interaction with other parts of the
system that you may not know of, leads to sporadic and erratic behaviour
seemingly unrelated to your code - then that discouragement is not 
helping anyone.

> Now, a way to philisophically enforce the "do" vs. 
> "represent" concept is to call the components by a new name: 
> services.  A service is a type of component that "does" 
> something or performs a service.

OK, got it.

I disagree, but that is for another time.

/LS


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Leo Sutic <le...@inspireinfrastructure.com>.
> From: Berin Loritsch [mailto:bloritsch@apache.org] 
> 
> > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > 
> > > From: Berin Loritsch [mailto:bloritsch@apache.org]
> > > 
> > > > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > > > 
>
> Hmm.  What we have here is a bad design.  Should the 
> container make up for your poor design?  Can you really get 
> away with only three instances in a pool with a web 
> environment?  Honestly, there is nothing in Cocoon that does 
> what you are talking about.

Yes, it is bad design. It is more than that - it is horrible design.

But admit one thing: It was not difficult to see that it was 
utterly atrocious!

I meant to use it to show a situation that may occur in a system. It
will
not be as clearly awful as the abomination I showed you, but *hidden*
in the code. I can show you more poor architecture:

  public void tailRecursive (int i) {
    if (i < 100) {
      mycomp = lookup (...);
      tailRecursive (i + 1);
    }
  }

Of course, the component should be passed in to the method. The point is
that you may have these patterns in your system on a much larger scale
*without knowing* it.

You will suddenly experience massive slowdowns and not know what is 
happening. After a few hours or days of going through code you realize
that
a certain method is being called multiple times. And that method does a 
lookup.
 
> You have something more than "I may want to implement this 
> poor design some day" that we can discuss?

As I said above, I tried to show you a pattern by distilling it
to a very short example. Apparently I failed so badly that you
thought I really advocated writing of such code.

> Why not discourage bad design?

Why not? Well, it depends on how that discouragement is done.
If designing your component poorly leads to YourCodeSucksErrors being
thrown all over the place (with correct line number and file info) the 
moment you start the server, then I'm all for it. 

But if, when you do something that is completely correct within the 
context of your component, but, in interaction with other parts of the
system that you may not know of, leads to sporadic and erratic behaviour
seemingly unrelated to your code - then that discouragement is not 
helping anyone.

> Now, a way to philisophically enforce the "do" vs. 
> "represent" concept is to call the components by a new name: 
> services.  A service is a type of component that "does" 
> something or performs a service.

OK, got it.

I disagree, but that is for another time.

/LS


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com] 
> 
> > From: Berin Loritsch [mailto:bloritsch@apache.org]
> > 
> > > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > > 
> > > Suppose you have a pool-max of 3:
> > > 
> > >    public void handleRequest () {
> > >       someMethod ();
> > >       someMethod ();      
> > >       someMethod ();
> > >       someMethod ();
> > >    }
> > 
> > And this is different from the current state of affairs, how?
> > If a request requires 5 transformer instances, and you have 
> > your pool max set to 3, you will still experience slow down.  
> > This is no different than automatically releasing a component 
> > when the request is handled.
> 
> The difference is this - with explicit release I can:
>   
>    public void someMethod () {
>       component = manager.lookup (ExpensiveButPooledComponent.ROLE);
>       ...
>        manager.release (component); <<<<<<<<<<<< Added this
>    }
> 
> And thus not drain the pool, as I only really need 1 instance.
> 
> As for whether this is efficient or not - that is not the 
> issue. The point is that with a per-request GC, you will need 
> to lookup all components you require *at the start of the 
> request* and then pass those around as you process the 
> request (to avoid too many lookups) - 
> unless you  are really sure that you will not end up in a situation 
> similar to the one I described. (That is, you repeatedly call
> a method that does a lookup during a single request. It will never be 
> as simple as the example: someMethod() will call someOtherMethod and 
> so on until, 20 steps up the call stack, you have a lookup. 
> And then, 20 more steps until the last method returns.)

Hmm.  What we have here is a bad design.  Should the container
make up for your poor design?  Can you really get away with only
three instances in a pool with a web environment?  Honestly,
there is nothing in Cocoon that does what you are talking about.

You have something more than "I may want to implement this poor
design some day" that we can discuss?

What you described here is woefully innefficient, and you will
have to refactor it completely in the very near future.  Why not
discourage bad design?


> > I am finding more and more what people are calling components
> > are nothing more than Objects that observe the Bridge 
> > pattern.  They implement an interface, introduce a few 
> > lifecycle methods, etc. If they are object then they should 
> > be treated as such.
> 
> Then what is a component? A Facade?

A component is a reusable binary that observes a public interface.
All component implementations of a specific public interface are
interchangeable.  The Bridge pattern states that the implementation
observes an external interface--you can't have components without
that.

However, the most successful components "do", not "represent".
It's a conceptual thing.  If you process a request by calling a
method on a component, then we are all good.  If you have a component
represent something and call multiple method calls on it, then
we run into the problems we are experiencing.

Now, a way to philisophically enforce the "do" vs. "represent"
concept is to call the components by a new name: services.  A service
is a type of component that "does" something or performs a service.


> > If a pooled object requires an explicit
> > return to a pool, than that decision should be made in the 
> > GeneratorManager, or the TransformerManager, etc.  Not in the 
> > core lookup mechanism.
> 
> What you propose is then that pooling is removed from
> the container itself. Pooling will be done by first using a 
> component manager to lookup another manager, and then use 
> that manager to obtain an instance from the pool. Am I correct?

That is one way of handling what you are talking about without
writing a GC routine.


> > >      ...means a load of GC policy parameters for the client.
> > 
> > ? I don't get this at all.
> 
> I meant "user", not "client". My bad.

It's still a container concern.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com] 
> 
> > From: Berin Loritsch [mailto:bloritsch@apache.org]
> > 
> > > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > > 
> > > Suppose you have a pool-max of 3:
> > > 
> > >    public void handleRequest () {
> > >       someMethod ();
> > >       someMethod ();      
> > >       someMethod ();
> > >       someMethod ();
> > >    }
> > 
> > And this is different from the current state of affairs, how?
> > If a request requires 5 transformer instances, and you have 
> > your pool max set to 3, you will still experience slow down.  
> > This is no different than automatically releasing a component 
> > when the request is handled.
> 
> The difference is this - with explicit release I can:
>   
>    public void someMethod () {
>       component = manager.lookup (ExpensiveButPooledComponent.ROLE);
>       ...
>        manager.release (component); <<<<<<<<<<<< Added this
>    }
> 
> And thus not drain the pool, as I only really need 1 instance.
> 
> As for whether this is efficient or not - that is not the 
> issue. The point is that with a per-request GC, you will need 
> to lookup all components you require *at the start of the 
> request* and then pass those around as you process the 
> request (to avoid too many lookups) - 
> unless you  are really sure that you will not end up in a situation 
> similar to the one I described. (That is, you repeatedly call
> a method that does a lookup during a single request. It will never be 
> as simple as the example: someMethod() will call someOtherMethod and 
> so on until, 20 steps up the call stack, you have a lookup. 
> And then, 20 more steps until the last method returns.)

Hmm.  What we have here is a bad design.  Should the container
make up for your poor design?  Can you really get away with only
three instances in a pool with a web environment?  Honestly,
there is nothing in Cocoon that does what you are talking about.

You have something more than "I may want to implement this poor
design some day" that we can discuss?

What you described here is woefully innefficient, and you will
have to refactor it completely in the very near future.  Why not
discourage bad design?


> > I am finding more and more what people are calling components
> > are nothing more than Objects that observe the Bridge 
> > pattern.  They implement an interface, introduce a few 
> > lifecycle methods, etc. If they are object then they should 
> > be treated as such.
> 
> Then what is a component? A Facade?

A component is a reusable binary that observes a public interface.
All component implementations of a specific public interface are
interchangeable.  The Bridge pattern states that the implementation
observes an external interface--you can't have components without
that.

However, the most successful components "do", not "represent".
It's a conceptual thing.  If you process a request by calling a
method on a component, then we are all good.  If you have a component
represent something and call multiple method calls on it, then
we run into the problems we are experiencing.

Now, a way to philisophically enforce the "do" vs. "represent"
concept is to call the components by a new name: services.  A service
is a type of component that "does" something or performs a service.


> > If a pooled object requires an explicit
> > return to a pool, than that decision should be made in the 
> > GeneratorManager, or the TransformerManager, etc.  Not in the 
> > core lookup mechanism.
> 
> What you propose is then that pooling is removed from
> the container itself. Pooling will be done by first using a 
> component manager to lookup another manager, and then use 
> that manager to obtain an instance from the pool. Am I correct?

That is one way of handling what you are talking about without
writing a GC routine.


> > >      ...means a load of GC policy parameters for the client.
> > 
> > ? I don't get this at all.
> 
> I meant "user", not "client". My bad.

It's still a container concern.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Berin Loritsch [mailto:bloritsch@apache.org] 
> 
> > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > 
> > Suppose you have a pool-max of 3:
> > 
> >    public void handleRequest () {
> >       someMethod ();
> >       someMethod ();      
> >       someMethod ();
> >       someMethod ();
> >    }
> 
> And this is different from the current state of affairs, how? 
> If a request requires 5 transformer instances, and you have 
> your pool max set to 3, you will still experience slow down.  
> This is no different than automatically releasing a component 
> when the request is handled.

The difference is this - with explicit release I can:
  
   public void someMethod () {
      component = manager.lookup (ExpensiveButPooledComponent.ROLE);
      ...
       manager.release (component); <<<<<<<<<<<< Added this
   }

And thus not drain the pool, as I only really need 1 instance.

As for whether this is efficient or not - that is not the issue.
The point is that with a per-request GC, you will need to lookup
all components you require *at the start of the request* and then pass
those around as you process the request (to avoid too many lookups) - 
unless you  are really sure that you will not end up in a situation 
similar to the one I described. (That is, you repeatedly call
a method that does a lookup during a single request. It will never be 
as simple as the example: someMethod() will call someOtherMethod and 
so on until, 20 steps up the call stack, you have a lookup. And then,
20 more steps until the last method returns.)

> I am finding more and more what people are calling components 
> are nothing more than Objects that observe the Bridge 
> pattern.  They implement an interface, introduce a few 
> lifecycle methods, etc. If they are object then they should 
> be treated as such.

Then what is a component? A Facade?

> If a pooled object requires an explicit 
> return to a pool, than that decision should be made in the 
> GeneratorManager, or the TransformerManager, etc.  Not in the 
> core lookup mechanism.

What you propose is then that pooling is removed from
the container itself. Pooling will be done by first using a component
manager to lookup another manager, and then use that manager
to obtain an instance from the pool. Am I correct?

> >      ...means a load of GC policy parameters for the client.
> 
> ? I don't get this at all.

I meant "user", not "client". My bad.

/LS


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Berin Loritsch [mailto:bloritsch@apache.org] 
> 
> > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > 
> > Suppose you have a pool-max of 3:
> > 
> >    public void handleRequest () {
> >       someMethod ();
> >       someMethod ();      
> >       someMethod ();
> >       someMethod ();
> >    }
> 
> And this is different from the current state of affairs, how? 
> If a request requires 5 transformer instances, and you have 
> your pool max set to 3, you will still experience slow down.  
> This is no different than automatically releasing a component 
> when the request is handled.

The difference is this - with explicit release I can:
  
   public void someMethod () {
      component = manager.lookup (ExpensiveButPooledComponent.ROLE);
      ...
       manager.release (component); <<<<<<<<<<<< Added this
   }

And thus not drain the pool, as I only really need 1 instance.

As for whether this is efficient or not - that is not the issue.
The point is that with a per-request GC, you will need to lookup
all components you require *at the start of the request* and then pass
those around as you process the request (to avoid too many lookups) - 
unless you  are really sure that you will not end up in a situation 
similar to the one I described. (That is, you repeatedly call
a method that does a lookup during a single request. It will never be 
as simple as the example: someMethod() will call someOtherMethod and 
so on until, 20 steps up the call stack, you have a lookup. And then,
20 more steps until the last method returns.)

> I am finding more and more what people are calling components 
> are nothing more than Objects that observe the Bridge 
> pattern.  They implement an interface, introduce a few 
> lifecycle methods, etc. If they are object then they should 
> be treated as such.

Then what is a component? A Facade?

> If a pooled object requires an explicit 
> return to a pool, than that decision should be made in the 
> GeneratorManager, or the TransformerManager, etc.  Not in the 
> core lookup mechanism.

What you propose is then that pooling is removed from
the container itself. Pooling will be done by first using a component
manager to lookup another manager, and then use that manager
to obtain an instance from the pool. Am I correct?

> >      ...means a load of GC policy parameters for the client.
> 
> ? I don't get this at all.

I meant "user", not "client". My bad.

/LS


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Berin Loritsch [mailto:bloritsch@apache.org]
 
<snip/>


> > > The GeneratorManager would handle the release() method, or it
would
> > > declare its semantics for use.
> > >
> > > Component use should not be a function of component lookup.
> >
> > Ok. What then will be contract between component manager and
> > user? When you call lookup(), what should you expect -
> > Component, ComponentSelector, ComponentGenerator, Pool,
> > something else?
> >
> > Or, I always will get XXXXXManager? Then, lifecycle
> > management will be moved to XXXXXManager, right?
> 
> You will always get the XXXXXManager.  So yes, lifecycle does
> move to XXXXXManager.  However, the XXXXXXManager can act as a
container
> for older components--that way we don't have to throw away the
> work we already have done.

NOW I SEE THE LIGHT! :)

I did not get this from your initial post.


<snip reason="agreed"/>


> > > Yes, but you wouldn't necessarily have your production (i.e. web)
> > > system doing this either.
> >
> > We have single J2EE container here for web and back-end...
> 
> But if your expensive 8 hour routine was handled by a session bean
> or something similar (JMS bound session bean?), then the Servlet
> environment is not affected by the processing.
> 
> See what I am saying?  It is asynchronous to the web environment.

I'm instantiating Avalon from enterprise application (ear), not from web
application (war) :)

<snip/>

> > Sometimes you have to use some legacy systems, which are not
> > necessarily written up to high-end Avalon standards...
> > SingleThreaded servlets should be considered as a way to
> > integrate such things.
> 
> You no longer have that option as of Servlet 2.3.

I won't miss it. But the point is - there is migration path.

Vadim



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


Re: [VOTE] RE: Removing some of the irons from the fire

Posted by Peter Donald <pe...@apache.org>.
At 10:03 AM 6/11/2002 +0200, you wrote:
> > From: Stefano Mazzocchi [mailto:stefano@apache.org]
> >
> > Oh, I know, I know, don't worry: I'm not resubscribing here
> > with my Cocoon-hat (if there is such a thing!) but with my
> > Avalon knight sword.
>
>We have developed firearms since you were here last. Here,
>have a SAW. ;)

Stefano was around back when we used to have daily flamefests over the 
color of the sky so he probably still got nukes sitting about ;)

 > At the same time, my status of committer in this project is
> > honorific and emeritus. For this reason, I don't consider
> > myself as a committer of this effort anymore (despite the
> > fact that the system allows me to commit, if I really wanted
> > to). My votes don't count, until you guys vote my emeritus
> > status back (but I don't want to call for such a votation right now).
>
>VOTE
>----
>Restore Stefano's committer status IMMEDIATELY.

Hell yes!

+1 +1 +1

Cheers,

Peter Donald
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"Faced with the choice between changing one's mind,
and proving that there is no need to do so - almost
everyone gets busy on the proof."
              - John Kenneth Galbraith
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


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


Re: Removing some of the irons from the fire [was Re: [Design] ContainerManageris under fire--let's find the best resolution]

Posted by Leo Simons <le...@apache.org>.
> Ok, let's rock and roll.

rock on dude, rock on!

- LSD



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


Re: [VOTE] RE: Removing some of the irons from the fire

Posted by Peter Royal <pr...@apache.org>.
On Tuesday 11 June 2002 04:03 am, Leo Sutic wrote:
> VOTE
> ----
> Restore Stefano's committer status IMMEDIATELY.

+1
-pete

-- 
peter royal -> proyal@apache.org

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


Re: [VOTE] RE: Removing some of the irons from the fire

Posted by Nicola Ken Barozzi <ni...@apache.org>.
Leo Simons wrote:
>>>At the same time, my status of committer in this project is 
>>>honorific and emeritus. For this reason, I don't consider 
>>>myself as a committer of this effort anymore (despite the 
>>>fact that the system allows me to commit, if I really wanted 
>>>to). My votes don't count, until you guys vote my emeritus 
>>>status back (but I don't want to call for such a votation right now).
>>
>>VOTE
>>----
>>Restore Stefano's committer status IMMEDIATELY.
>>
>>Reason: Either Stefano has common sense or he hasn't. If he 
>>has, he will not vote when he knows he does not understand the 
>>issue. If he does not have common sense, well, will he care about
>>any "no-you-may-not-vote-or-change-CVS" rule? (No.)
>>
>>+1 from me.
> 
> 
> +1 if he is =)
> 

+1

This is the first time I'm voting Stefano in, and not viceversa... :-D

-- 
Nicola Ken Barozzi                   nicolaken@apache.org
             - verba volant, scripta manent -
    (discussions get forgotten, just code remains)
---------------------------------------------------------------------


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


Re: [VOTE] RE: Removing some of the irons from the fire

Posted by Leo Simons <le...@apache.org>.
> > At the same time, my status of committer in this project is 
> > honorific and emeritus. For this reason, I don't consider 
> > myself as a committer of this effort anymore (despite the 
> > fact that the system allows me to commit, if I really wanted 
> > to). My votes don't count, until you guys vote my emeritus 
> > status back (but I don't want to call for such a votation right now).
> 
> VOTE
> ----
> Restore Stefano's committer status IMMEDIATELY.
> 
> Reason: Either Stefano has common sense or he hasn't. If he 
> has, he will not vote when he knows he does not understand the 
> issue. If he does not have common sense, well, will he care about
> any "no-you-may-not-vote-or-change-CVS" rule? (No.)
> 
> +1 from me.

+1 if he is =)

- Leo Simons



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


RE: [VOTE] RE: Removing some of the irons from the fire

Posted by Berin Loritsch <bl...@apache.org>.
> From: Peter Donald [mailto:peter@apache.org] 
> 
> On Tue, 11 Jun 2002 23:02, Berin Loritsch wrote:
> > > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > >
> > > > From: Stefano Mazzocchi [mailto:stefano@apache.org]
> > > >
> > > > Oh, I know, I know, don't worry: I'm not resubscribing 
> here with 
> > > > my Cocoon-hat (if there is such a thing!) but with my Avalon 
> > > > knight sword.
> > >
> > > We have developed firearms since you were here last. Here, have a 
> > > SAW. ;)
> >
> > I prefer a good Katana like the McClaud boys in Highlander. 
> They are 
> > less bulky, and more precise.  Their purpose is to slice, 
> not bash.  
> > :)  (That and I just got one for my 30th in May).
> 
> ooer - now I jealous.


:)

I just have to learn how to use it correctly.  Eventually I will
invest in a "real" one (one that was designed as a weapon and
not a display piece)--but those cost at least $1200 USD.  Perhaps
it will be a reward for when I achieve the skill to warrant one....


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


Re: [VOTE] RE: Removing some of the irons from the fire

Posted by Peter Donald <pe...@apache.org>.
On Tue, 11 Jun 2002 23:02, Berin Loritsch wrote:
> > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> >
> > > From: Stefano Mazzocchi [mailto:stefano@apache.org]
> > >
> > > Oh, I know, I know, don't worry: I'm not resubscribing here
> > > with my Cocoon-hat (if there is such a thing!) but with my
> > > Avalon knight sword.
> >
> > We have developed firearms since you were here last. Here,
> > have a SAW. ;)
>
> I prefer a good Katana like the McClaud boys in Highlander.
> They are less bulky, and more precise.  Their purpose is to
> slice, not bash.  :)  (That and I just got one for my 30th
> in May).

ooer - now I jealous.

-- 
Cheers,

Peter Donald
------------------------------------------------------------
 militant agnostic: i don't know, and you don't know either.
------------------------------------------------------------ 


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


ATTN: Stefano

Posted by Leo Sutic <le...@inspireinfrastructure.com>.
Stefano: Welcome back, dude, mate, geezer!

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

VOTE
----
Restore Stefano's committer status IMMEDIATELY.

> From: Berin Loritsch [mailto:bloritsch@apache.org] 
> I vote +1 to have him back in full swing.

Leo Simons wrote:
> +1 if he is =)

> From: Nicola Ken Barozzi [mailto:nicolaken@apache.org] 
>
> +1
> 
> This is the first time I'm voting Stefano in, and not viceversa... :-D

> From: Peter Donald [mailto:peter@apache.org] 
>
> Hell yes!
> 
> +1 +1 +1

> From: Leo Sutic
>
> +1 from me.


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


RE: [VOTE] RE: Removing some of the irons from the fire

Posted by Berin Loritsch <bl...@apache.org>.
> From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com] 
> 
> > From: Berin Loritsch [mailto:bloritsch@apache.org]
> >
> > > > At the same time, my status of committer in this project is
> > > > honorific and emeritus. For this reason, I don't consider 
> > myself as
> > > > a committer of this effort anymore (despite the fact that
> > the system
> > > > allows me to commit, if I really wanted to). My votes
> > don't count,
> > > > until you guys vote my emeritus status back (but I don't want to
> > > > call for such a votation
> > > right now).
> > > 
> > > VOTE
> > > ----
> > > Restore Stefano's committer status IMMEDIATELY.
> > > 
> > > Reason: Either Stefano has common sense or he hasn't. If 
> he has, he 
> > > will not vote when he knows he does not understand the 
> issue. If he 
> > > does not have common sense, well, will he care about any 
> > > "no-you-may-not-vote-or-change-CVS" rule? (No.)
> > > 
> > > +1 from me.
> > 
> > Stefano's CVS privaledges have not been revoked (at least to
> > my knowledge).  All he said was that he wants to regain the 
> > respect in this community and earn what he already has.
> 
> Yes - and that is what I am proposing. He explicitly says 
> that he will not vote until we (as a formality) vote him back as a
> committer: "My votes don't count, until you guys vote my emeritus 
> status back (but I don't want to call for such a votation right 
> now)."
> 
> As I stated, if he has common sense he'll know when to vote and 
> when not to. If he doesn't have it, well, he won't remember any
> *self-imposed* "no-you-may-not-vote-or-change-CVS" rule.
> 
> So give the guy a pat on the back, a "welcome back, dude, mate, 
> geezer (British meaning)" and see what happens. What's the worst 
> outcome? 
> 
>  1) A load of idiot mails and 
> 
>  2) and a lot of votes cast for "the wrong" proposals.
> 
> I won't comment (1), but if ONE person can, by voting, get 
> something moronic through, then the voting process is broken 
> or we're all equally moronic (by not vetoing).


I doubt we will have that kind of trouble with Stefano.  He's got
some decent mettle, and he's pretty intelligent (he does have a
doctorate....).

I have no qualms with him, and I think he would be a great asset
to the Avalon community.  I vote +1 to have him back in full swing.


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


RE: [VOTE] RE: Removing some of the irons from the fire

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Berin Loritsch [mailto:bloritsch@apache.org] 
>
> > > At the same time, my status of committer in this project is 
> > > honorific and emeritus. For this reason, I don't consider 
> myself as 
> > > a committer of this effort anymore (despite the fact that 
> the system 
> > > allows me to commit, if I really wanted to). My votes 
> don't count, 
> > > until you guys vote my emeritus status back (but I don't want to 
> > > call for such a votation
> > right now).
> > 
> > VOTE
> > ----
> > Restore Stefano's committer status IMMEDIATELY.
> > 
> > Reason: Either Stefano has common sense or he hasn't. If he
> > has, he will not vote when he knows he does not understand the 
> > issue. If he does not have common sense, well, will he care 
> > about any "no-you-may-not-vote-or-change-CVS" rule? (No.)
> > 
> > +1 from me.
> 
> Stefano's CVS privaledges have not been revoked (at least to 
> my knowledge).  All he said was that he wants to regain the 
> respect in this community and earn what he already has.

Yes - and that is what I am proposing. He explicitly says that
he will not vote until we (as a formality) vote him back as a
committer: "My votes don't count, until you guys vote my emeritus 
status back (but I don't want to call for such a votation right 
now)."

As I stated, if he has common sense he'll know when to vote and 
when not to. If he doesn't have it, well, he won't remember any
*self-imposed* "no-you-may-not-vote-or-change-CVS" rule.

So give the guy a pat on the back, a "welcome back, dude, mate, 
geezer (British meaning)" and see what happens. What's the worst 
outcome? 

 1) A load of idiot mails and 

 2) and a lot of votes cast for "the wrong" proposals.

I won't comment (1), but if ONE person can, by voting, get 
something moronic through, then the voting process is broken or
we're all equally moronic (by not vetoing).

/LS


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


RE: [VOTE] RE: Removing some of the irons from the fire

Posted by Berin Loritsch <bl...@apache.org>.
> From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com] 
> 
> > From: Stefano Mazzocchi [mailto:stefano@apache.org]
> > 
> > Oh, I know, I know, don't worry: I'm not resubscribing here
> > with my Cocoon-hat (if there is such a thing!) but with my 
> > Avalon knight sword.
> 
> We have developed firearms since you were here last. Here,
> have a SAW. ;)

I prefer a good Katana like the McClaud boys in Highlander.
They are less bulky, and more precise.  Their purpose is to
slice, not bash.  :)  (That and I just got one for my 30th
in May).


> > At the same time, my status of committer in this project is
> > honorific and emeritus. For this reason, I don't consider 
> > myself as a committer of this effort anymore (despite the 
> > fact that the system allows me to commit, if I really wanted 
> > to). My votes don't count, until you guys vote my emeritus 
> > status back (but I don't want to call for such a votation 
> right now).
> 
> VOTE
> ----
> Restore Stefano's committer status IMMEDIATELY.
> 
> Reason: Either Stefano has common sense or he hasn't. If he 
> has, he will not vote when he knows he does not understand the 
> issue. If he does not have common sense, well, will he care 
> about any "no-you-may-not-vote-or-change-CVS" rule? (No.)
> 
> +1 from me.

Stefano's CVS privaledges have not been revoked (at least to my
knowledge).  All he said was that he wants to regain the respect
in this community and earn what he already has.


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


[VOTE] RE: Removing some of the irons from the fire

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Stefano Mazzocchi [mailto:stefano@apache.org] 
> 
> Oh, I know, I know, don't worry: I'm not resubscribing here 
> with my Cocoon-hat (if there is such a thing!) but with my 
> Avalon knight sword.

We have developed firearms since you were here last. Here,
have a SAW. ;)
 
> At the same time, my status of committer in this project is 
> honorific and emeritus. For this reason, I don't consider 
> myself as a committer of this effort anymore (despite the 
> fact that the system allows me to commit, if I really wanted 
> to). My votes don't count, until you guys vote my emeritus 
> status back (but I don't want to call for such a votation right now).

VOTE
----
Restore Stefano's committer status IMMEDIATELY.

Reason: Either Stefano has common sense or he hasn't. If he 
has, he will not vote when he knows he does not understand the 
issue. If he does not have common sense, well, will he care about
any "no-you-may-not-vote-or-change-CVS" rule? (No.)

+1 from me.

/LS



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


Re: Removing some of the irons from the fire [was Re: [Design] ContainerManageris under fire--let's find the best resolution]

Posted by Stefano Mazzocchi <st...@apache.org>.
Stephen McConnell wrote:
> 
> Stefano Mazzocchi wrote:
> 
> >You guys are working on Avalon 5, great, I want to be part of this. I'm
> >resubscribing to avalon-dev right now.
> >
> >
> 
> Cool.
> I have seen your name scattered around variouse sources so I guess
> this means your guilty by implication ;-)

Of course, I am. I left Avalon when Berin and Peter came along since I
had to graduate from college and I didn't have time to follow both
Cocoon and Avalon at the same time. I think it's time to clean up my own
mess.

> >But some of you (all?) are cocoon lovers and you see many things that
> >Cocoon might do in better ways.
> >
> 
> Just for reference there is a lot of use of Avalon in areas that
> are totally independent of the cocoon world.

Oh, I know, I know, don't worry: I'm not resubscribing here with my
Cocoon-hat (if there is such a thing!) but with my Avalon knight sword.

At the same time, my status of committer in this project is honorific
and emeritus. For this reason, I don't consider myself as a committer of
this effort anymore (despite the fact that the system allows me to
commit, if I really wanted to). My votes don't count, until you guys
vote my emeritus status back (but I don't want to call for such a
votation right now).

So, in short: my opinions count as anybody else's and my votes won't be
pending. This is because I don't want people to think "look at him: he
comes back after all this time and wants to rule the place". No way. I
have to learn a bunch of things that you guys did in the past and I hope
I'll be able to catch up and contribute something.

I'm here to help, not to impose anything.
 
> Just the ctivities I'm involved in include the OpenORB project which
> makes extensive use of the framework and a number of Excalibur
> resources (not ECM). Services include a full-blown ORB, Persistent
> State Service, Naming, Time, event and notification services, a couple
> of compilers, and a Trader service.  Beyond that, there are industrial
> projects dealing with Business Process Management, Community and
> Collaboration policy and execution for in the B2B context, business
> service registration and discovery systems, PKI frameworks, ....
> not to mention all of the projects under avalon-apps.

Don't worry, Steve. I'm fully aware of the fact that Avalon is not
simply the foundation of Cocoon and James, but it's getting momentum in
many different areas, expecially in those service-oriented areas where
Avalon was invented to fit in.
 
> Looking forward to you thoughts on A5.

Thanks, this is very appreciated.

I might ask stupid questions in the near future, hopefully to get up to
speed with what you guys did in the last year of so. I apologize in
advance for this.

Ok, let's rock and roll.

-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<st...@apache.org>                             Friedrich Nietzsche
--------------------------------------------------------------------



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


Re: Removing some of the irons from the fire [was Re: [Design] ContainerManager is under fire--let's find the best resolution]

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

Stefano Mazzocchi wrote:

>You guys are working on Avalon 5, great, I want to be part of this. I'm
>resubscribing to avalon-dev right now.
>  
>

Cool.
I have seen your name scattered around variouse sources so I guess
this means your guilty by implication ;-)

>But some of you (all?) are cocoon lovers and you see many things that
>Cocoon might do in better ways. 
>

Just for reference there is a lot of use of Avalon in areas that
are totally independent of the cocoon world.

Just the ctivities I'm involved in include the OpenORB project which
makes extensive use of the framework and a number of Excalibur
resources (not ECM). Services include a full-blown ORB, Persistent
State Service, Naming, Time, event and notification services, a couple
of compilers, and a Trader service.  Beyond that, there are industrial
projects dealing with Business Process Management, Community and
Collaboration policy and execution for in the B2B context, business
service registration and discovery systems, PKI frameworks, ....
not to mention all of the projects under avalon-apps.

Looking forward to you thoughts on A5.

Cheers, Steve.

-- 

Stephen J. McConnell

OSM SARL
digital products for a global economy
mailto:mcconnell@osm.net
http://www.osm.net




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


Re: Removing some of the irons from the fire [was Re: [Design] ContainerManager is under fire--let's find the best resolution]

Posted by "Andrew C. Oliver" <ac...@apache.org>.
>
>
>
>So, while the first 2 points don't belong to this list (no matter how
>much Cocoon is tied to avalon), only the third does. But I will be
>*STRONGLY* against changing any deep structure before Cocoon stabilizes
>from a usability point of view.
>  
>
+1 - Amen.  There are many areas that need incremental improvement 
before the foundation gets ripped
up again.

>While I understand the concepts that Berin proposes, I think they are
>something for Cocoon 3. There are *much* more important things to do on
>Cocoon (docs, the flowmap integration, blocks) before even trying to fix
>deep architectural imperfections (which are yet to be demostrated,
>anyhow)
>
>SoC, damn it.
>
>So, let's move the discussion on Avalon 5 in avalon-dev and when that
>effort is done, we'll move it over to cocoon-dev and discuss a possible
>Cocoon 3.0 internal branch... but with three/four books coming out, it
>would be a *SUICIDE* even to start talking about changing those
>interfaces right now, no matter how elegant the new framework will be.
>  
>
+1 - I know many folks interested in using Cocoon that ripping up the 
foundation would seriously
turn off.

>In case you didn't know, there are companies outthere who are using
>Cocoon or evaluating cocoon for their commercial use and investing
>millions of dollars on our architectural solidity. 
>
>This doesn't mean that we can't improve, but we must be *very* concerned
>about the timing, the reasons and the intentions.
>  
>
And thats why its 2.1 but not 3.0.  2.1 implies improvement but not 
revolutionary change.  Granted with
the opensource environment and the way I know a how a certain contingent 
of this community work.
(Build brilliant stuff that only they understand, provide no 
documentation or explanation and wonder why no one uses it
and every one creates their own.)  So perhaps once 2.0.3 is out a new 
branch 3.0 should start for those who
want to start a revolution.  The 2.1, 2.2, etc series can continue and 
mature and 3.0 can be marked "absolutely do not
use unless you like exceptions".  The book writers can watch the commit 
logs and start their "second editions" ;-).  
But devils and angels alike atack those who have three or more CVS branches.

-Andy

>Hope this is clear to everybody.
>
>  
>




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


Removing some of the irons from the fire [was Re: [Design] ContainerManager is under fire--let's find the best resolution]

Posted by Stefano Mazzocchi <st...@apache.org>.
People,

the idea I had of Avalon kept with my hopes: it is a meme, an infective
programming notion that sticks in your head and that can't be further
removed.

Luckily, it also moved from a meme to code than to a community effort: I
can't say I'm entirely happy with what happens over at Avalon-land, but
I love the fact that the effort is moving along (rumors say that Turbine
might get to use Avalon in the future, this is a great thing for
everybody, IMO)

You guys are working on Avalon 5, great, I want to be part of this. I'm
resubscribing to avalon-dev right now.

But some of you (all?) are cocoon lovers and you see many things that
Cocoon might do in better ways. I can't disagree, but this is making too
many irons in the fire. The fire is cooling down and I bet not many
people followed the somewhat harsh discussion between Berin, Vadim and
Leo. I couldn't myself, there was too lack of focus for my personal
taste.

The things that were put on the table (all at once) were:

 1) removing ComponentSelector
 2) removing the release() method
 3) change the behavior of the core cocoon internals

I guess that's a little too much to discuss in a single thread, don't
you think?

So, while the first 2 points don't belong to this list (no matter how
much Cocoon is tied to avalon), only the third does. But I will be
*STRONGLY* against changing any deep structure before Cocoon stabilizes
from a usability point of view.

While I understand the concepts that Berin proposes, I think they are
something for Cocoon 3. There are *much* more important things to do on
Cocoon (docs, the flowmap integration, blocks) before even trying to fix
deep architectural imperfections (which are yet to be demostrated,
anyhow)

SoC, damn it.

So, let's move the discussion on Avalon 5 in avalon-dev and when that
effort is done, we'll move it over to cocoon-dev and discuss a possible
Cocoon 3.0 internal branch... but with three/four books coming out, it
would be a *SUICIDE* even to start talking about changing those
interfaces right now, no matter how elegant the new framework will be.

In case you didn't know, there are companies outthere who are using
Cocoon or evaluating cocoon for their commercial use and investing
millions of dollars on our architectural solidity. 

This doesn't mean that we can't improve, but we must be *very* concerned
about the timing, the reasons and the intentions.

Hope this is clear to everybody.

-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<st...@apache.org>                             Friedrich Nietzsche
--------------------------------------------------------------------



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


Removing some of the irons from the fire [was Re: [Design] ContainerManager is under fire--let's find the best resolution]

Posted by Stefano Mazzocchi <st...@apache.org>.
People,

the idea I had of Avalon kept with my hopes: it is a meme, an infective
programming notion that sticks in your head and that can't be further
removed.

Luckily, it also moved from a meme to code than to a community effort: I
can't say I'm entirely happy with what happens over at Avalon-land, but
I love the fact that the effort is moving along (rumors say that Turbine
might get to use Avalon in the future, this is a great thing for
everybody, IMO)

You guys are working on Avalon 5, great, I want to be part of this. I'm
resubscribing to avalon-dev right now.

But some of you (all?) are cocoon lovers and you see many things that
Cocoon might do in better ways. I can't disagree, but this is making too
many irons in the fire. The fire is cooling down and I bet not many
people followed the somewhat harsh discussion between Berin, Vadim and
Leo. I couldn't myself, there was too lack of focus for my personal
taste.

The things that were put on the table (all at once) were:

 1) removing ComponentSelector
 2) removing the release() method
 3) change the behavior of the core cocoon internals

I guess that's a little too much to discuss in a single thread, don't
you think?

So, while the first 2 points don't belong to this list (no matter how
much Cocoon is tied to avalon), only the third does. But I will be
*STRONGLY* against changing any deep structure before Cocoon stabilizes
from a usability point of view.

While I understand the concepts that Berin proposes, I think they are
something for Cocoon 3. There are *much* more important things to do on
Cocoon (docs, the flowmap integration, blocks) before even trying to fix
deep architectural imperfections (which are yet to be demostrated,
anyhow)

SoC, damn it.

So, let's move the discussion on Avalon 5 in avalon-dev and when that
effort is done, we'll move it over to cocoon-dev and discuss a possible
Cocoon 3.0 internal branch... but with three/four books coming out, it
would be a *SUICIDE* even to start talking about changing those
interfaces right now, no matter how elegant the new framework will be.

In case you didn't know, there are companies outthere who are using
Cocoon or evaluating cocoon for their commercial use and investing
millions of dollars on our architectural solidity. 

This doesn't mean that we can't improve, but we must be *very* concerned
about the timing, the reasons and the intentions.

Hope this is clear to everybody.

-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<st...@apache.org>                             Friedrich Nietzsche
--------------------------------------------------------------------



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Berin Loritsch [mailto:bloritsch@apache.org] 
> 
> > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > 
> > > From: Berin Loritsch [mailto:bloritsch@apache.org]
> > > 
> > > > Or, I always will get XXXXXManager? Then, lifecycle
> > management will
> > > > be moved to XXXXXManager, right?
> > > 
> > > You will always get the XXXXXManager.  So yes, lifecycle 
> does move 
> > > to XXXXXManager.  However, the XXXXXXManager can act as a 
> container 
> > > for older components--that way we don't have to throw 
> away the work 
> > > we already have done.
> > 
> > Berin,
> > 
> > OK how about this: You get all managers you need in
> > compose(). Then when you need a component you call the 
> > manager you obtained in compose(). If this is what you mean, 
> > then I'm fine with it. Some extra code, but it's just like 
> > EJB:s XXXXXHome interface.
> 
> That's exactly what I mean.
> 

I have some reservations regarding the release() method
or equivalent below, but it seems like we're on the same
wavelength.
 
> > Second, how do you handle switching between pooled and threadsafe
> > implementations of a component interface? The way I see it, 
> > you have to assume that the component is pooled and thus it 
> > must have some way of being released. So does this mean that 
> > we will have a standardized XXXXXManager interface with a 
> > getInstance() and a release() method? Or will the XXXXManager 
> > be specific to each component interface? Can you give samples 
> > of three different XXXXManager interfaces, just 
> > so I can see what differences there may be?
> 
> By removing the release() method from the CM, we place the 
> responsibility on the XXXXManager.  That means that the 
> XXXXManager has the release() method--if it is necessary.

By "necessary" do you mean this:
Either the Manager, or the component itself,
will typically provide some method, after which it has
been called,
the component is invalidated and maybe returned to a pool.
This method *must* be called by the client.

So, DataSourceComponent will not have a release()
as you would call close() on the connection instead.
The two examples with XMLSource and sink do not have
release(), as the endDocument event signals the end-of-
duty-cycle for the component.
But if there wasn't any such methods (that is, the
component itself does not provide a method for the
client to say "I'm done with you"), the Manager
must provide a release(XXXX component) method or
equivalent.

Is this correct?

Furthermore, the  associated XXXXManager interface is not
implementation specific. You can switch from pooled to
threadsafe and back without changing the way you use it.

Is this correct?
 
> You see, the existence of the ComponentSelector does change 
> the way we write our components.  Either our components will 
> break if the does not exist, or the logic to handle either 
> situation will add unnecessary bulk.

Exactly, and that is why it must die. The idea was good -
you get selection of components orthogonal from the components
themselves. But the problem you specify pretty much makes them
useless.

But - where do you put the lookup(String role, Object hint)
method (or equivalent)? In the CM interface? It would appear
that you'd put it in the XXXXXManager interface.
Does this mean that you will merge selectors with Managers?
Or will a ComponentSelector be an XXXXXManagerSelector?

Finally, I would like this name change for A5:

         ComponentManager -> ComponentDirectory
         XXXXXManager     -> ComponentManager

I think it would reduce confusion. But that's for later....

/LS


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Berin Loritsch [mailto:bloritsch@apache.org] 
> 
> > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > 
> > > From: Berin Loritsch [mailto:bloritsch@apache.org]
> > > 
> > > > Or, I always will get XXXXXManager? Then, lifecycle
> > management will
> > > > be moved to XXXXXManager, right?
> > > 
> > > You will always get the XXXXXManager.  So yes, lifecycle 
> does move 
> > > to XXXXXManager.  However, the XXXXXXManager can act as a 
> container 
> > > for older components--that way we don't have to throw 
> away the work 
> > > we already have done.
> > 
> > Berin,
> > 
> > OK how about this: You get all managers you need in
> > compose(). Then when you need a component you call the 
> > manager you obtained in compose(). If this is what you mean, 
> > then I'm fine with it. Some extra code, but it's just like 
> > EJB:s XXXXXHome interface.
> 
> That's exactly what I mean.
> 

I have some reservations regarding the release() method
or equivalent below, but it seems like we're on the same
wavelength.
 
> > Second, how do you handle switching between pooled and threadsafe
> > implementations of a component interface? The way I see it, 
> > you have to assume that the component is pooled and thus it 
> > must have some way of being released. So does this mean that 
> > we will have a standardized XXXXXManager interface with a 
> > getInstance() and a release() method? Or will the XXXXManager 
> > be specific to each component interface? Can you give samples 
> > of three different XXXXManager interfaces, just 
> > so I can see what differences there may be?
> 
> By removing the release() method from the CM, we place the 
> responsibility on the XXXXManager.  That means that the 
> XXXXManager has the release() method--if it is necessary.

By "necessary" do you mean this:
Either the Manager, or the component itself,
will typically provide some method, after which it has
been called,
the component is invalidated and maybe returned to a pool.
This method *must* be called by the client.

So, DataSourceComponent will not have a release()
as you would call close() on the connection instead.
The two examples with XMLSource and sink do not have
release(), as the endDocument event signals the end-of-
duty-cycle for the component.
But if there wasn't any such methods (that is, the
component itself does not provide a method for the
client to say "I'm done with you"), the Manager
must provide a release(XXXX component) method or
equivalent.

Is this correct?

Furthermore, the  associated XXXXManager interface is not
implementation specific. You can switch from pooled to
threadsafe and back without changing the way you use it.

Is this correct?
 
> You see, the existence of the ComponentSelector does change 
> the way we write our components.  Either our components will 
> break if the does not exist, or the logic to handle either 
> situation will add unnecessary bulk.

Exactly, and that is why it must die. The idea was good -
you get selection of components orthogonal from the components
themselves. But the problem you specify pretty much makes them
useless.

But - where do you put the lookup(String role, Object hint)
method (or equivalent)? In the CM interface? It would appear
that you'd put it in the XXXXXManager interface.
Does this mean that you will merge selectors with Managers?
Or will a ComponentSelector be an XXXXXManagerSelector?

Finally, I would like this name change for A5:

         ComponentManager -> ComponentDirectory
         XXXXXManager     -> ComponentManager

I think it would reduce confusion. But that's for later....

/LS


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Vadim Gritsenko [mailto:vadim.gritsenko@verizon.net] 
> 
> Shouldn't some standard (default, etc) Manager will be available?

And what, pray tell, would it look like?  The COmponentManger as it is
defined is a lookup mechanism.  Nothing more.  The ComponentSelector
pattern was designed to allow multiple choices for the same component
type based on a hint.

The thing is that many times all you need is Role/purpose or Role/Name
combo for that.  If all you need is that, then the new CM interface
will help you out.

It's like the difference between a regular connection and an SSL
connection.  Sometimes you need to choose programatically.  In those
cases, all we need to do is lookup(ConnectionManager.ROLE, "SSL"),
which is good enough.

It is when you require something more fine grained than a *per thread*
granularity.  In other words, if there is a good chance that there are
several component instances in any given thread of execution, then
something needs to change.  Either it needs a more fine grained manager,
or the components themselves need to change.


> I really not exactly understand necessity of different 
> managers, or, let's put it this way, absence of some 
> standard/default manager interface. I got the part that 
> lookup and component lifecycle will be implemented by two 
> different entities, not the one component manager (as of now) 
> - and I have no issues with this.
> 
> But I don't get why you force different manager for every 
> different component. Then, you won't be free anymore to 
> switch between different component implementations (or change 
> implementation) - you will break XXXXXManager interface which 
> depends on implementation of the component.


Look, for many components (more the rule than the exception)
you won't need a XXXXManager.  If the interface is intelligently
designed, then there is no reason for an XXXXManager.  In Cocoon's
case, it needs it to provide backwards compatibility while it
improves its component model.

Truthfully the component in question is the XXXXManager.  The
actual instance returned is more an artifact of the processing.
The XXXXManager allows more intelligent treatment of the types
of information/components/etc. that it manages than a generic
interface or solution could ever do.


> 
> To illustrate the point: manager of ThreadSafe component 
> won't have release(), manager of non-disposable component 
> also won't have release(). If you ever decide that your 
> component must be disposable or it must be poolable you have 
> to change XXXXXManager interface, and, as a result, rewrite 
> *all* the clients of this interface.

To illustrate my point: if there is a possibility that the
XXXXManager has pooled objects, then you have a choice:

* Hide the pooling mechanism into the normal use of the artifact
  (ContentHandler, XMLSource, JDBC Connection)
* Or explicitly force the client to remember to return the pooled
  artifact

Both have their challenges.  I prefer to hide the pooling mechanism
as much as possible--but that is my preference.  It would be
ludicrous to build a new Manager for each lifestyle (creational
policy).

The point is that not every type of component, or every approach
works for all people.  We want to move that choice, that concern,
into the hands of the component developers and not into the lookup
mechanism.  Otherwise the normal use code of working with a
ComponentManager becomes more complicated than necessary--for the
benefit of only a few components.


> What about cast to XXXXXManager?
> 
>   MyManager mm = (MyManager)cm.lookup("role");
> 
> While removing one cast another was added.

Not necessarily.  When we resolve components, we have to cast them.
That
doesn't change.  But compare that with a ComponentSelector (as we have
them now):

ComponentSelector selector = (ComponentSelector)
        cm.lookup(DataSourceComponent.ROLE + "Selector");

DataSourceComponent dsc = (DataSourceComponent)
selector.select("secondDB");
Connection conn = dsc.getConnection();

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

Compare that to the new and improved way:

DataSourceComponent dsc = (DataSourceComponent)
        cm.lookup(DataSourceCompoennt.ROLE, "secondDB");

Connection conn = dsc.getConnection();

It saves both an additional lookup, and an additional cast.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Vadim Gritsenko [mailto:vadim.gritsenko@verizon.net] 
> 
> Shouldn't some standard (default, etc) Manager will be available?

And what, pray tell, would it look like?  The COmponentManger as it is
defined is a lookup mechanism.  Nothing more.  The ComponentSelector
pattern was designed to allow multiple choices for the same component
type based on a hint.

The thing is that many times all you need is Role/purpose or Role/Name
combo for that.  If all you need is that, then the new CM interface
will help you out.

It's like the difference between a regular connection and an SSL
connection.  Sometimes you need to choose programatically.  In those
cases, all we need to do is lookup(ConnectionManager.ROLE, "SSL"),
which is good enough.

It is when you require something more fine grained than a *per thread*
granularity.  In other words, if there is a good chance that there are
several component instances in any given thread of execution, then
something needs to change.  Either it needs a more fine grained manager,
or the components themselves need to change.


> I really not exactly understand necessity of different 
> managers, or, let's put it this way, absence of some 
> standard/default manager interface. I got the part that 
> lookup and component lifecycle will be implemented by two 
> different entities, not the one component manager (as of now) 
> - and I have no issues with this.
> 
> But I don't get why you force different manager for every 
> different component. Then, you won't be free anymore to 
> switch between different component implementations (or change 
> implementation) - you will break XXXXXManager interface which 
> depends on implementation of the component.


Look, for many components (more the rule than the exception)
you won't need a XXXXManager.  If the interface is intelligently
designed, then there is no reason for an XXXXManager.  In Cocoon's
case, it needs it to provide backwards compatibility while it
improves its component model.

Truthfully the component in question is the XXXXManager.  The
actual instance returned is more an artifact of the processing.
The XXXXManager allows more intelligent treatment of the types
of information/components/etc. that it manages than a generic
interface or solution could ever do.


> 
> To illustrate the point: manager of ThreadSafe component 
> won't have release(), manager of non-disposable component 
> also won't have release(). If you ever decide that your 
> component must be disposable or it must be poolable you have 
> to change XXXXXManager interface, and, as a result, rewrite 
> *all* the clients of this interface.

To illustrate my point: if there is a possibility that the
XXXXManager has pooled objects, then you have a choice:

* Hide the pooling mechanism into the normal use of the artifact
  (ContentHandler, XMLSource, JDBC Connection)
* Or explicitly force the client to remember to return the pooled
  artifact

Both have their challenges.  I prefer to hide the pooling mechanism
as much as possible--but that is my preference.  It would be
ludicrous to build a new Manager for each lifestyle (creational
policy).

The point is that not every type of component, or every approach
works for all people.  We want to move that choice, that concern,
into the hands of the component developers and not into the lookup
mechanism.  Otherwise the normal use code of working with a
ComponentManager becomes more complicated than necessary--for the
benefit of only a few components.


> What about cast to XXXXXManager?
> 
>   MyManager mm = (MyManager)cm.lookup("role");
> 
> While removing one cast another was added.

Not necessarily.  When we resolve components, we have to cast them.
That
doesn't change.  But compare that with a ComponentSelector (as we have
them now):

ComponentSelector selector = (ComponentSelector)
        cm.lookup(DataSourceComponent.ROLE + "Selector");

DataSourceComponent dsc = (DataSourceComponent)
selector.select("secondDB");
Connection conn = dsc.getConnection();

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

Compare that to the new and improved way:

DataSourceComponent dsc = (DataSourceComponent)
        cm.lookup(DataSourceCompoennt.ROLE, "secondDB");

Connection conn = dsc.getConnection();

It saves both an additional lookup, and an additional cast.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Berin Loritsch [mailto:bloritsch@apache.org]
> 
> > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> >
> > > From: Berin Loritsch [mailto:bloritsch@apache.org]
> > >
> > > > Or, I always will get XXXXXManager? Then, lifecycle
> > > > management will
> > > > be moved to XXXXXManager, right?
> > >
> > > You will always get the XXXXXManager.  So yes, lifecycle does
> > > move to XXXXXManager.  However, the XXXXXXManager can act as
> > > a container for older components--that way we don't have to
> > > throw away the work we already have done.
> >
> > Berin,
> >
> > OK how about this: You get all managers you need in
> > compose(). Then when you need a component you call the
> > manager you obtained in compose(). If this is what you mean,
> > then I'm fine with it. Some extra code, but it's just like
> > EJB:s XXXXXHome interface.
> 
> That's exactly what I mean.
> 
> 
> > Second, how do you handle switching between pooled and threadsafe
> > implementations of a component interface? The way I see it,
> > you have to assume that the component is pooled and thus it
> > must have some way of being released. So does this mean that
> > we will have a standardized XXXXXManager interface with a
> > getInstance() and a release() method? Or will the XXXXManager
> > be specific to each component interface? Can you give samples
> > of three different XXXXManager interfaces, just
> > so I can see what differences there may be?
> 
> By removing the release() method from the CM, we place the
> responsibility on the XXXXManager.  That means that the
> XXXXManager has the release() method--if it is necessary.
> 
> The XXXXManager would be specific to the type of component or
> processing artifact that it manages.  This allows for more
> intelligent resource management and integration with other
> components.
> 
> As to your request for the XXXXXManager interfaces, here you
> go:
> 
> interface DataSourceComponent
> {
>     Connection getConnection(); // current interface
>     Connection getConnection(String name); // for next version
> }
> 
> interface GeneratorManager
> {
>     XMLSource getSource( String type, Map objectModel, String source,
>                             Parameters params );
> }
> 
> interface SerializerManager
> {
>     ContentHandler getSink( String type, Map objectModel, Parameters
> param,
>                             OutputStream out );
> }

Shouldn't some standard (default, etc) Manager will be available?

I really not exactly understand necessity of different managers, or,
let's put it this way, absence of some standard/default manager
interface. I got the part that lookup and component lifecycle will be
implemented by two different entities, not the one component manager (as
of now) - and I have no issues with this.

But I don't get why you force different manager for every different
component. Then, you won't be free anymore to switch between different
component implementations (or change implementation) - you will break
XXXXXManager interface which depends on implementation of the component.

To illustrate the point: manager of ThreadSafe component won't have
release(), manager of non-disposable component also won't have
release(). If you ever decide that your component must be disposable or
it must be poolable you have to change XXXXXManager interface, and, as a
result, rewrite *all* the clients of this interface.


> The DataSourceComponent does need to be extended because it is
> threadsafe, and there are potentially several different databases
> one system may need to interact with.  Usually there is a default,
> which is why the original getConnection() would remain.  But it would
> be wasteful to have to go to a Selector in *some* environments, but
> get the DataSourceComponent directly in *other* environments.
> 
> You see, the existence of the ComponentSelector does change the way
> we write our components.  Either our components will break if the
> does not exist, or the logic to handle either situation will add
> unnecessary bulk.
> 
> The GeneratorManager and the SerializerManager are slightly different
> in that we don't have a "source" parameter but have an "out" parameter
> instead.
> 
> Another benefit of this approach is that we don't have to do casting,
> and risk ClassCastExceptions at runtime.

What about cast to XXXXXManager?

  MyManager mm = (MyManager)cm.lookup("role");

While removing one cast another was added.


> > Third, am I the only one getting three copies of every email on
> > avalon-dev and cocoon-dev?
> 
> No, It happens when we hit reply-all, and the mail client adds the
> original sender along with the two mail lists.  I am getting them
> two.

Same here.

Vadim



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Berin Loritsch [mailto:bloritsch@apache.org]
> 
> > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> >
> > > From: Berin Loritsch [mailto:bloritsch@apache.org]
> > >
> > > > Or, I always will get XXXXXManager? Then, lifecycle
> > > > management will
> > > > be moved to XXXXXManager, right?
> > >
> > > You will always get the XXXXXManager.  So yes, lifecycle does
> > > move to XXXXXManager.  However, the XXXXXXManager can act as
> > > a container for older components--that way we don't have to
> > > throw away the work we already have done.
> >
> > Berin,
> >
> > OK how about this: You get all managers you need in
> > compose(). Then when you need a component you call the
> > manager you obtained in compose(). If this is what you mean,
> > then I'm fine with it. Some extra code, but it's just like
> > EJB:s XXXXXHome interface.
> 
> That's exactly what I mean.
> 
> 
> > Second, how do you handle switching between pooled and threadsafe
> > implementations of a component interface? The way I see it,
> > you have to assume that the component is pooled and thus it
> > must have some way of being released. So does this mean that
> > we will have a standardized XXXXXManager interface with a
> > getInstance() and a release() method? Or will the XXXXManager
> > be specific to each component interface? Can you give samples
> > of three different XXXXManager interfaces, just
> > so I can see what differences there may be?
> 
> By removing the release() method from the CM, we place the
> responsibility on the XXXXManager.  That means that the
> XXXXManager has the release() method--if it is necessary.
> 
> The XXXXManager would be specific to the type of component or
> processing artifact that it manages.  This allows for more
> intelligent resource management and integration with other
> components.
> 
> As to your request for the XXXXXManager interfaces, here you
> go:
> 
> interface DataSourceComponent
> {
>     Connection getConnection(); // current interface
>     Connection getConnection(String name); // for next version
> }
> 
> interface GeneratorManager
> {
>     XMLSource getSource( String type, Map objectModel, String source,
>                             Parameters params );
> }
> 
> interface SerializerManager
> {
>     ContentHandler getSink( String type, Map objectModel, Parameters
> param,
>                             OutputStream out );
> }

Shouldn't some standard (default, etc) Manager will be available?

I really not exactly understand necessity of different managers, or,
let's put it this way, absence of some standard/default manager
interface. I got the part that lookup and component lifecycle will be
implemented by two different entities, not the one component manager (as
of now) - and I have no issues with this.

But I don't get why you force different manager for every different
component. Then, you won't be free anymore to switch between different
component implementations (or change implementation) - you will break
XXXXXManager interface which depends on implementation of the component.

To illustrate the point: manager of ThreadSafe component won't have
release(), manager of non-disposable component also won't have
release(). If you ever decide that your component must be disposable or
it must be poolable you have to change XXXXXManager interface, and, as a
result, rewrite *all* the clients of this interface.


> The DataSourceComponent does need to be extended because it is
> threadsafe, and there are potentially several different databases
> one system may need to interact with.  Usually there is a default,
> which is why the original getConnection() would remain.  But it would
> be wasteful to have to go to a Selector in *some* environments, but
> get the DataSourceComponent directly in *other* environments.
> 
> You see, the existence of the ComponentSelector does change the way
> we write our components.  Either our components will break if the
> does not exist, or the logic to handle either situation will add
> unnecessary bulk.
> 
> The GeneratorManager and the SerializerManager are slightly different
> in that we don't have a "source" parameter but have an "out" parameter
> instead.
> 
> Another benefit of this approach is that we don't have to do casting,
> and risk ClassCastExceptions at runtime.

What about cast to XXXXXManager?

  MyManager mm = (MyManager)cm.lookup("role");

While removing one cast another was added.


> > Third, am I the only one getting three copies of every email on
> > avalon-dev and cocoon-dev?
> 
> No, It happens when we hit reply-all, and the mail client adds the
> original sender along with the two mail lists.  I am getting them
> two.

Same here.

Vadim



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com] 
> 
> > From: Berin Loritsch [mailto:bloritsch@apache.org]
> > 
> > > Or, I always will get XXXXXManager? Then, lifecycle 
> management will 
> > > be moved to XXXXXManager, right?
> > 
> > You will always get the XXXXXManager.  So yes, lifecycle does
> > move to XXXXXManager.  However, the XXXXXXManager can act as 
> > a container for older components--that way we don't have to 
> > throw away the work we already have done.
> 
> Berin,
> 
> OK how about this: You get all managers you need in 
> compose(). Then when you need a component you call the 
> manager you obtained in compose(). If this is what you mean, 
> then I'm fine with it. Some extra code, but it's just like 
> EJB:s XXXXXHome interface.

That's exactly what I mean.


> Second, how do you handle switching between pooled and threadsafe 
> implementations of a component interface? The way I see it, 
> you have to assume that the component is pooled and thus it 
> must have some way of being released. So does this mean that 
> we will have a standardized XXXXXManager interface with a 
> getInstance() and a release() method? Or will the XXXXManager 
> be specific to each component interface? Can you give samples 
> of three different XXXXManager interfaces, just 
> so I can see what differences there may be?

By removing the release() method from the CM, we place the
responsibility on the XXXXManager.  That means that the
XXXXManager has the release() method--if it is necessary.

The XXXXManager would be specific to the type of component or
processing artifact that it manages.  This allows for more
intelligent resource management and integration with other
components.

As to your request for the XXXXXManager interfaces, here you
go:

interface DataSourceComponent
{
    Connection getConnection(); // current interface
    Connection getConnection(String name); // for next version
}

interface GeneratorManager
{
    XMLSource getSource( String type, Map objectModel, String source,
                            Parameters params );
}

interface SerializerManager
{
    ContentHandler getSink( String type, Map objectModel, Parameters
param,
                            OutputStream out );
}


The DataSourceComponent does need to be extended because it is
threadsafe, and there are potentially several different databases
one system may need to interact with.  Usually there is a default,
which is why the original getConnection() would remain.  But it would
be wasteful to have to go to a Selector in *some* environments, but
get the DataSourceComponent directly in *other* environments.

You see, the existence of the ComponentSelector does change the way
we write our components.  Either our components will break if the
does not exist, or the logic to handle either situation will add
unnecessary bulk.

The GeneratorManager and the SerializerManager are slightly different
in that we don't have a "source" parameter but have an "out" parameter
instead.

Another benefit of this approach is that we don't have to do casting,
and risk ClassCastExceptions at runtime.

> 
> Third, am I the only one getting three copies of every email on 
> avalon-dev and cocoon-dev?

No, It happens when we hit reply-all, and the mail client adds the
original sender along with the two mail lists.  I am getting them
two.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com] 
> 
> > From: Berin Loritsch [mailto:bloritsch@apache.org]
> > 
> > > Or, I always will get XXXXXManager? Then, lifecycle 
> management will 
> > > be moved to XXXXXManager, right?
> > 
> > You will always get the XXXXXManager.  So yes, lifecycle does
> > move to XXXXXManager.  However, the XXXXXXManager can act as 
> > a container for older components--that way we don't have to 
> > throw away the work we already have done.
> 
> Berin,
> 
> OK how about this: You get all managers you need in 
> compose(). Then when you need a component you call the 
> manager you obtained in compose(). If this is what you mean, 
> then I'm fine with it. Some extra code, but it's just like 
> EJB:s XXXXXHome interface.

That's exactly what I mean.


> Second, how do you handle switching between pooled and threadsafe 
> implementations of a component interface? The way I see it, 
> you have to assume that the component is pooled and thus it 
> must have some way of being released. So does this mean that 
> we will have a standardized XXXXXManager interface with a 
> getInstance() and a release() method? Or will the XXXXManager 
> be specific to each component interface? Can you give samples 
> of three different XXXXManager interfaces, just 
> so I can see what differences there may be?

By removing the release() method from the CM, we place the
responsibility on the XXXXManager.  That means that the
XXXXManager has the release() method--if it is necessary.

The XXXXManager would be specific to the type of component or
processing artifact that it manages.  This allows for more
intelligent resource management and integration with other
components.

As to your request for the XXXXXManager interfaces, here you
go:

interface DataSourceComponent
{
    Connection getConnection(); // current interface
    Connection getConnection(String name); // for next version
}

interface GeneratorManager
{
    XMLSource getSource( String type, Map objectModel, String source,
                            Parameters params );
}

interface SerializerManager
{
    ContentHandler getSink( String type, Map objectModel, Parameters
param,
                            OutputStream out );
}


The DataSourceComponent does need to be extended because it is
threadsafe, and there are potentially several different databases
one system may need to interact with.  Usually there is a default,
which is why the original getConnection() would remain.  But it would
be wasteful to have to go to a Selector in *some* environments, but
get the DataSourceComponent directly in *other* environments.

You see, the existence of the ComponentSelector does change the way
we write our components.  Either our components will break if the
does not exist, or the logic to handle either situation will add
unnecessary bulk.

The GeneratorManager and the SerializerManager are slightly different
in that we don't have a "source" parameter but have an "out" parameter
instead.

Another benefit of this approach is that we don't have to do casting,
and risk ClassCastExceptions at runtime.

> 
> Third, am I the only one getting three copies of every email on 
> avalon-dev and cocoon-dev?

No, It happens when we hit reply-all, and the mail client adds the
original sender along with the two mail lists.  I am getting them
two.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Berin Loritsch [mailto:bloritsch@apache.org] 
> 
> > Or, I always will get XXXXXManager? Then, lifecycle
> > management will be moved to XXXXXManager, right?
> 
> You will always get the XXXXXManager.  So yes, lifecycle does 
> move to XXXXXManager.  However, the XXXXXXManager can act as 
> a container for older components--that way we don't have to 
> throw away the work we already have done.

Berin,

OK how about this: You get all managers you need in compose().
Then when you need a component you call the manager you obtained in
compose(). If this is what you mean, then I'm fine with it. Some extra
code, but it's just like EJB:s XXXXXHome interface.

Second, how do you handle switching between pooled and threadsafe 
implementations of a component interface? The way I see it, you have
to assume that the component is pooled and thus it must have some
way of being released. So does this mean that we will have a
standardized
XXXXXManager interface with a getInstance() and a release() method?
Or will the XXXXManager be specific to each component interface?
Can you give samples of three different XXXXManager interfaces, just 
so I can see what differences there may be?

Third, am I the only one getting three copies of every email on 
avalon-dev and cocoon-dev?

/LS


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Berin Loritsch [mailto:bloritsch@apache.org] 
> 
> > Or, I always will get XXXXXManager? Then, lifecycle
> > management will be moved to XXXXXManager, right?
> 
> You will always get the XXXXXManager.  So yes, lifecycle does 
> move to XXXXXManager.  However, the XXXXXXManager can act as 
> a container for older components--that way we don't have to 
> throw away the work we already have done.

Berin,

OK how about this: You get all managers you need in compose().
Then when you need a component you call the manager you obtained in
compose(). If this is what you mean, then I'm fine with it. Some extra
code, but it's just like EJB:s XXXXXHome interface.

Second, how do you handle switching between pooled and threadsafe 
implementations of a component interface? The way I see it, you have
to assume that the component is pooled and thus it must have some
way of being released. So does this mean that we will have a
standardized
XXXXXManager interface with a getInstance() and a release() method?
Or will the XXXXManager be specific to each component interface?
Can you give samples of three different XXXXManager interfaces, just 
so I can see what differences there may be?

Third, am I the only one getting three copies of every email on 
avalon-dev and cocoon-dev?

/LS


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Berin Loritsch [mailto:bloritsch@apache.org]
 
<snip/>


> > > The GeneratorManager would handle the release() method, or it
would
> > > declare its semantics for use.
> > >
> > > Component use should not be a function of component lookup.
> >
> > Ok. What then will be contract between component manager and
> > user? When you call lookup(), what should you expect -
> > Component, ComponentSelector, ComponentGenerator, Pool,
> > something else?
> >
> > Or, I always will get XXXXXManager? Then, lifecycle
> > management will be moved to XXXXXManager, right?
> 
> You will always get the XXXXXManager.  So yes, lifecycle does
> move to XXXXXManager.  However, the XXXXXXManager can act as a
container
> for older components--that way we don't have to throw away the
> work we already have done.

NOW I SEE THE LIGHT! :)

I did not get this from your initial post.


<snip reason="agreed"/>


> > > Yes, but you wouldn't necessarily have your production (i.e. web)
> > > system doing this either.
> >
> > We have single J2EE container here for web and back-end...
> 
> But if your expensive 8 hour routine was handled by a session bean
> or something similar (JMS bound session bean?), then the Servlet
> environment is not affected by the processing.
> 
> See what I am saying?  It is asynchronous to the web environment.

I'm instantiating Avalon from enterprise application (ear), not from web
application (war) :)

<snip/>

> > Sometimes you have to use some legacy systems, which are not
> > necessarily written up to high-end Avalon standards...
> > SingleThreaded servlets should be considered as a way to
> > integrate such things.
> 
> You no longer have that option as of Servlet 2.3.

I won't miss it. But the point is - there is migration path.

Vadim



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Robert Mouat <ro...@mouat.net>.
Berin Loritsch wrote:

> > > The GeneratorManager would handle the release() method, or it would 
> > > declare its semantics for use.
> > > 
> > > Component use should not be a function of component lookup.
> > 
> > Ok. What then will be contract between component manager and 
> > user? When you call lookup(), what should you expect - 
> > Component, ComponentSelector, ComponentGenerator, Pool, 
> > something else?
> > 
> > Or, I always will get XXXXXManager? Then, lifecycle 
> > management will be moved to XXXXXManager, right?
> 
> You will always get the XXXXXManager.  So yes, lifecycle does
> move to XXXXXManager.  However, the XXXXXXManager can act as a container
> for older components--that way we don't have to throw away the
> work we already have done.

This sounds like it will lead to something like:

  class ComponentManagerHelper {

    private ComponentManager cm;
    private Map managers = new HashMap();

    public ComponentManagerHelper( ComponentManager cm )
    {
      this.cm = cm;
    }

    public Object lookup( String role )
    {
      XXXXXManager manager = cm.lookup( role );
      Object component = manager.lookup( role );
      managers.put( component, manager );
      return component;
    }

    public void release( component ) 
    {
      manager = managers.remove( component );
      if ( manager instanceof Releasable )
        ((Releasable) manager).release( component );
    }

  }

and the typical use would be:

  public void compose( ComponentManager cm )
  {
    ComponentManagerHelper cmh = new ComponentManagerHelper( cm );

    myComponent = cmh.lookup( SomeComponent.ROLE )

    // throw away reference to cm and use cmh instead

  }

and

    cmh.release( MyComponent );


in which case why don't we save the client this step and do something
like:

  abstract class AbstractComponentManager implements ComponentManager
  {
    private Map managers = new HashMap();
 
    public Object lookup( String role )
    {
      XXXXXManager manager = lookupManager( role );
      Object component = manager.lookup( role );
      managers.put( component, manager );
      return component;
    }
 
    public void release( component )
    {
      manager = managers.remove( component );
      if ( manager instanceof Releasable )
        ((Releasable) manager).release( component );
    }

    abstract protected XXXXXManager lookupManager( role );

  }


The reason I suggest this (which may seem at odds with my postings in
other branches of this thread) is that I think forcing the XXXXXManager
makes the framework a little heavier -- and with the
AbstractComponentManager above you still get the benefits but the
components dont need to see it (e.g. you dont need to create an
XXXXXManager to do unit testing).

Robert.



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Vadim Gritsenko [mailto:vadim.gritsenko@verizon.net] 
> > Furthermore, a GeneratorManager can declare its own 
> semantics.  If you 
> > want the release() method there, then there are no issues 
> conflicting 
> > with overall CM design.
> 
> Ok, it means that for Generator I should create 
> GeneratorManager, and for XXXXX - XXXXXManager.

Yep.


> > > I think discussion here was carried away from topic... 
> Architecture
> of
> > > future Cocoon should be discussed separately. I was 
> trying only to 
> > > clarify how container will handle absence of the release() method.
> > 
> > The GeneratorManager would handle the release() method, or it would 
> > declare its semantics for use.
> > 
> > Component use should not be a function of component lookup.
> 
> Ok. What then will be contract between component manager and 
> user? When you call lookup(), what should you expect - 
> Component, ComponentSelector, ComponentGenerator, Pool, 
> something else?
> 
> Or, I always will get XXXXXManager? Then, lifecycle 
> management will be moved to XXXXXManager, right?

You will always get the XXXXXManager.  So yes, lifecycle does
move to XXXXXManager.  However, the XXXXXXManager can act as a container
for older components--that way we don't have to throw away the
work we already have done.


> Good thing about ECM is that component writer can easily 
> switch ThreadSafe -> Poolable and vice versa without breaking 
> any code using his component. Will this be the case for new CM?

It is a function of the Container--not the CM.  The ECM mixes the
concerns of a Container and a lookup mechanism.  It is not optimal.
Fortress is an example of a Container with a separate CM.  It is
even easier for the container or administrator to control the creation
policy for components.  It pulls that meta-info from a file.  That
way we don't run into strange things that happen in Inheritance
hierarchies that would owtherwise confuse the ECM.


> Also, I remembered about component factories (when component 
> is created on every request and destroyed on release). Will 
> this be supported with this new release()less design? You can 
> say that these single-use components are evil (as single-use 
> servlets), but this is the only choice for some legacy 
> applications/libaries.

That control is moved to your XXXXXXXManager.  It is not the
CM's responsibility to manage your component instances--it is
the container's responsibility.

> > 
> > Yes, but you wouldn't necessarily have your production (i.e. web)
> system
> > doing this either.
> 
> We have single J2EE container here for web and back-end...

But if your expensive 8 hour routine was handled by a session bean
or something similar (JMS bound session bean?), then the Servlet
environment is not affected by the processing.

See what I am saying?  It is asynchronous to the web environment.


> > > J2EE has REQUIRES_NEW transaction management attribute 
> for the EJB 
> > > method. If you have such methods (is it considered wrong design?),
> all
> > > required for this method TxResource-s should be looked 
> up, thus you 
> > > will have more then one instance of a component.
> > 
> > J2EE also allowed you to declare Servlets as single use (not one 
> > instance per thread or sharing an instance among 
> threads)--does that 
> > make it correct design?  It was a serious bottleneck allowing a Q&D 
> > hack.
> 
> Sometimes you have to use some legacy systems, which are not 
> necessarily written up to high-end Avalon standards... 
> SingleThreaded servlets should be considered as a way to 
> integrate such things.

You no longer have that option as of Servlet 2.3.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Vadim Gritsenko [mailto:vadim.gritsenko@verizon.net] 
> > Furthermore, a GeneratorManager can declare its own 
> semantics.  If you 
> > want the release() method there, then there are no issues 
> conflicting 
> > with overall CM design.
> 
> Ok, it means that for Generator I should create 
> GeneratorManager, and for XXXXX - XXXXXManager.

Yep.


> > > I think discussion here was carried away from topic... 
> Architecture
> of
> > > future Cocoon should be discussed separately. I was 
> trying only to 
> > > clarify how container will handle absence of the release() method.
> > 
> > The GeneratorManager would handle the release() method, or it would 
> > declare its semantics for use.
> > 
> > Component use should not be a function of component lookup.
> 
> Ok. What then will be contract between component manager and 
> user? When you call lookup(), what should you expect - 
> Component, ComponentSelector, ComponentGenerator, Pool, 
> something else?
> 
> Or, I always will get XXXXXManager? Then, lifecycle 
> management will be moved to XXXXXManager, right?

You will always get the XXXXXManager.  So yes, lifecycle does
move to XXXXXManager.  However, the XXXXXXManager can act as a container
for older components--that way we don't have to throw away the
work we already have done.


> Good thing about ECM is that component writer can easily 
> switch ThreadSafe -> Poolable and vice versa without breaking 
> any code using his component. Will this be the case for new CM?

It is a function of the Container--not the CM.  The ECM mixes the
concerns of a Container and a lookup mechanism.  It is not optimal.
Fortress is an example of a Container with a separate CM.  It is
even easier for the container or administrator to control the creation
policy for components.  It pulls that meta-info from a file.  That
way we don't run into strange things that happen in Inheritance
hierarchies that would owtherwise confuse the ECM.


> Also, I remembered about component factories (when component 
> is created on every request and destroyed on release). Will 
> this be supported with this new release()less design? You can 
> say that these single-use components are evil (as single-use 
> servlets), but this is the only choice for some legacy 
> applications/libaries.

That control is moved to your XXXXXXXManager.  It is not the
CM's responsibility to manage your component instances--it is
the container's responsibility.

> > 
> > Yes, but you wouldn't necessarily have your production (i.e. web)
> system
> > doing this either.
> 
> We have single J2EE container here for web and back-end...

But if your expensive 8 hour routine was handled by a session bean
or something similar (JMS bound session bean?), then the Servlet
environment is not affected by the processing.

See what I am saying?  It is asynchronous to the web environment.


> > > J2EE has REQUIRES_NEW transaction management attribute 
> for the EJB 
> > > method. If you have such methods (is it considered wrong design?),
> all
> > > required for this method TxResource-s should be looked 
> up, thus you 
> > > will have more then one instance of a component.
> > 
> > J2EE also allowed you to declare Servlets as single use (not one 
> > instance per thread or sharing an instance among 
> threads)--does that 
> > make it correct design?  It was a serious bottleneck allowing a Q&D 
> > hack.
> 
> Sometimes you have to use some legacy systems, which are not 
> necessarily written up to high-end Avalon standards... 
> SingleThreaded servlets should be considered as a way to 
> integrate such things.

You no longer have that option as of Servlet 2.3.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Berin Loritsch [mailto:bloritsch@apache.org]
> 
> > From: Vadim Gritsenko [mailto:vadim.gritsenko@verizon.net]
> >
> >
> > And work itself will be done in XMLSource/XMLPipeline/XMLSink. I got
> > that part. Hope performance will not be sacrificed by this move (you
> > will be new()ing this objects all the time)
> 
> Modern JVMs have better GC policies, and is quicker at handling 
> trivial objects.  You can still do Pooling, but it is handled by 
> the GeneratorManager.

Good.


> > > The new way would probably add a GeneratorManager for this 
> > > purpose. However,
> > > the artifact returned is preinitialized with everything it
> > > needs. The
> > > GeneratorManager, TransformerManager, and SerializerManager 
> > > can all take care
> > > of usage semantics if it handles pooled items.
> >
> > How they differ from ComponentSelector?
> 
> 
> More focused management policies, type safety (no more casting), and
> the "setUp()" method becomes the query method.  This allows more
> specific criteria for Generator types.
> 
> Furthermore, a GeneratorManager can declare its own semantics.  If you
> want the release() method there, then there are no issues conflicting
> with overall CM design.

Ok, it means that for Generator I should create GeneratorManager, and
for XXXXX - XXXXXManager.


> > I think discussion here was carried away from topic... Architecture
of
> > future Cocoon should be discussed separately. I was trying only to
> > clarify how container will handle absence of the release() method.
> 
> The GeneratorManager would handle the release() method, or it would
> declare its semantics for use.
> 
> Component use should not be a function of component lookup.

Ok. What then will be contract between component manager and user? When
you call lookup(), what should you expect - Component,
ComponentSelector, ComponentGenerator, Pool, something else?

Or, I always will get XXXXXManager? Then, lifecycle management will be
moved to XXXXXManager, right?


Good thing about ECM is that component writer can easily switch
ThreadSafe -> Poolable and vice versa without breaking any code using
his component. Will this be the case for new CM?


Also, I remembered about component factories (when component is created
on every request and destroyed on release). Will this be supported with
this new release()less design? You can say that these single-use
components are evil (as single-use servlets), but this is the only
choice for some legacy applications/libaries.


<snip/>

> > > A serializer should _*never*_ modify the content of the XML.  It
> > > can only modify the binary stream's representation of it.
> >
> > It does not. I guess you did not understand my thought. Point is:
> > endDocument is no indication to component manager that this
> > component is
> > free.
> 
> Forget GC for now.  Can you see how it can be done with a
> GeneratorManager?

I think yes.

<snip/>

> > Transformers now invoke: Source, LDAP connections, SQL connections,
> > XML:DB collections, files, Loggers... What makes serializer
> > so special?
> > Why code, say, XML->PDF code again and not reuse? Or
> > SAX->XML-in-a-String?
> 
> What about the sitemap handling the separate sinks, you know the
> pipeline multiplexer/demultiplexer concept?

Kind of invented it... WritableSource is the first step towards this.


> > > Ever.  It is the Sitemap's responsibility to manage all
> > > pipelines--whether they have branched or not.  Once all
> > > processing for
> > > a request is done--and the sitemap or at least the Cocoon
container
> > > knows this unequivicably--then it can reclaim the components.
> >
> >     Exactly!
> >
> > Cocoon *container* knows! But this is *not* indicated by some
> > endDocument() on some (intermediate) component in the middle of
> > processing!
> 
> Which was my original point.  The endDocument() was an example of
> another possibility.  IF you want to extend the SAX spec that says
> a contenthandler  is done when endDocument() is called and it
> can free resources, then that's on you.

Aha! So it was an example of possibility of enhancing ContentHandler
contract. Ok. This is no different from Connection.close() - it is
stated in contract that connection is no good after close().


> > But when and how you collect and return to the pool components used
> > during processing? Right now this is done as soon as component is
not
> > needed. If you to do this only once and only after *whole*
> > processing is
> > finished you are bound to hold (critical) resources longer then
> > necessary.
> 
> That is a price of GC systems.  However, you can make critical
resources
> less prone to extended resource holding by providing something akin to
> the DataSourceComponent, even if you make the release() method part of
> the managing component.

So it is still possible with Avalon 5. Good.

<snip/>

> > > > There are situations when transaction takes hours to process
> > > > (I do not mean DB transaction here). How this will happen?
> > >
> > > Wow.  Hours? Then you need to think of a different way of 
> > > handling that
> > > transaction. That is a deeper design issue that needs
> > > serious thought for that application.
> >
> > Simple example: print invoices at the end of the month. You don't
want
> > to hold lots of critical resources during, say, 8 hour process in
> > top-level component which performs this, right?
> 
> Yes, but you wouldn't necessarily have your production (i.e. web)
system
> doing this either. 

We have single J2EE container here for web and back-end...


> It would be an offline process kicked off from the
> commandline
> (chron daemon) or something else along those lines.  It is an
> asynchronous process. 

It is async, it could be kicked off from cron, but it would run in the
container (cause it will use all the application logic - residing in the
container).


> Smarter component design will allow you to avoid necessary
> pooling,
> causing fewer resources to be used, less resource contention, and
> ultimately higher performance.

I agree that no pooling == higher performance. Best performing program
is ThreadSafe block in assembler.

<snip/>

> > J2EE has REQUIRES_NEW transaction management attribute for the EJB
> > method. If you have such methods (is it considered wrong design?),
all
> > required for this method TxResource-s should be looked up,
> > thus you will
> > have more then one instance of a component.
> 
> J2EE also allowed you to declare Servlets as single use (not one
> instance
> per thread or sharing an instance among threads)--does that make it
> correct design?  It was a serious bottleneck allowing a Q&D hack.

Sometimes you have to use some legacy systems, which are not necessarily
written up to high-end Avalon standards... SingleThreaded servlets
should be considered as a way to integrate such things.


> > > BTW, The Fortress
> > > container has a much shorter release() cycle because it handles
> > > the logic asyncronously.  It may take a little longer getting the
> > > instance into the pool, but it doesn't affect the critical path.
> >
> > This will have to be benchmarked then.
> 
> There is a performance benchmark that uses ECM/Fortress in Fortress's
> test code.  It has been compared.

Cool.

Vadim



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Berin Loritsch [mailto:bloritsch@apache.org]
> 
> > From: Vadim Gritsenko [mailto:vadim.gritsenko@verizon.net]
> >
> >
> > And work itself will be done in XMLSource/XMLPipeline/XMLSink. I got
> > that part. Hope performance will not be sacrificed by this move (you
> > will be new()ing this objects all the time)
> 
> Modern JVMs have better GC policies, and is quicker at handling 
> trivial objects.  You can still do Pooling, but it is handled by 
> the GeneratorManager.

Good.


> > > The new way would probably add a GeneratorManager for this 
> > > purpose. However,
> > > the artifact returned is preinitialized with everything it
> > > needs. The
> > > GeneratorManager, TransformerManager, and SerializerManager 
> > > can all take care
> > > of usage semantics if it handles pooled items.
> >
> > How they differ from ComponentSelector?
> 
> 
> More focused management policies, type safety (no more casting), and
> the "setUp()" method becomes the query method.  This allows more
> specific criteria for Generator types.
> 
> Furthermore, a GeneratorManager can declare its own semantics.  If you
> want the release() method there, then there are no issues conflicting
> with overall CM design.

Ok, it means that for Generator I should create GeneratorManager, and
for XXXXX - XXXXXManager.


> > I think discussion here was carried away from topic... Architecture
of
> > future Cocoon should be discussed separately. I was trying only to
> > clarify how container will handle absence of the release() method.
> 
> The GeneratorManager would handle the release() method, or it would
> declare its semantics for use.
> 
> Component use should not be a function of component lookup.

Ok. What then will be contract between component manager and user? When
you call lookup(), what should you expect - Component,
ComponentSelector, ComponentGenerator, Pool, something else?

Or, I always will get XXXXXManager? Then, lifecycle management will be
moved to XXXXXManager, right?


Good thing about ECM is that component writer can easily switch
ThreadSafe -> Poolable and vice versa without breaking any code using
his component. Will this be the case for new CM?


Also, I remembered about component factories (when component is created
on every request and destroyed on release). Will this be supported with
this new release()less design? You can say that these single-use
components are evil (as single-use servlets), but this is the only
choice for some legacy applications/libaries.


<snip/>

> > > A serializer should _*never*_ modify the content of the XML.  It
> > > can only modify the binary stream's representation of it.
> >
> > It does not. I guess you did not understand my thought. Point is:
> > endDocument is no indication to component manager that this
> > component is
> > free.
> 
> Forget GC for now.  Can you see how it can be done with a
> GeneratorManager?

I think yes.

<snip/>

> > Transformers now invoke: Source, LDAP connections, SQL connections,
> > XML:DB collections, files, Loggers... What makes serializer
> > so special?
> > Why code, say, XML->PDF code again and not reuse? Or
> > SAX->XML-in-a-String?
> 
> What about the sitemap handling the separate sinks, you know the
> pipeline multiplexer/demultiplexer concept?

Kind of invented it... WritableSource is the first step towards this.


> > > Ever.  It is the Sitemap's responsibility to manage all
> > > pipelines--whether they have branched or not.  Once all
> > > processing for
> > > a request is done--and the sitemap or at least the Cocoon
container
> > > knows this unequivicably--then it can reclaim the components.
> >
> >     Exactly!
> >
> > Cocoon *container* knows! But this is *not* indicated by some
> > endDocument() on some (intermediate) component in the middle of
> > processing!
> 
> Which was my original point.  The endDocument() was an example of
> another possibility.  IF you want to extend the SAX spec that says
> a contenthandler  is done when endDocument() is called and it
> can free resources, then that's on you.

Aha! So it was an example of possibility of enhancing ContentHandler
contract. Ok. This is no different from Connection.close() - it is
stated in contract that connection is no good after close().


> > But when and how you collect and return to the pool components used
> > during processing? Right now this is done as soon as component is
not
> > needed. If you to do this only once and only after *whole*
> > processing is
> > finished you are bound to hold (critical) resources longer then
> > necessary.
> 
> That is a price of GC systems.  However, you can make critical
resources
> less prone to extended resource holding by providing something akin to
> the DataSourceComponent, even if you make the release() method part of
> the managing component.

So it is still possible with Avalon 5. Good.

<snip/>

> > > > There are situations when transaction takes hours to process
> > > > (I do not mean DB transaction here). How this will happen?
> > >
> > > Wow.  Hours? Then you need to think of a different way of 
> > > handling that
> > > transaction. That is a deeper design issue that needs
> > > serious thought for that application.
> >
> > Simple example: print invoices at the end of the month. You don't
want
> > to hold lots of critical resources during, say, 8 hour process in
> > top-level component which performs this, right?
> 
> Yes, but you wouldn't necessarily have your production (i.e. web)
system
> doing this either. 

We have single J2EE container here for web and back-end...


> It would be an offline process kicked off from the
> commandline
> (chron daemon) or something else along those lines.  It is an
> asynchronous process. 

It is async, it could be kicked off from cron, but it would run in the
container (cause it will use all the application logic - residing in the
container).


> Smarter component design will allow you to avoid necessary
> pooling,
> causing fewer resources to be used, less resource contention, and
> ultimately higher performance.

I agree that no pooling == higher performance. Best performing program
is ThreadSafe block in assembler.

<snip/>

> > J2EE has REQUIRES_NEW transaction management attribute for the EJB
> > method. If you have such methods (is it considered wrong design?),
all
> > required for this method TxResource-s should be looked up,
> > thus you will
> > have more then one instance of a component.
> 
> J2EE also allowed you to declare Servlets as single use (not one
> instance
> per thread or sharing an instance among threads)--does that make it
> correct design?  It was a serious bottleneck allowing a Q&D hack.

Sometimes you have to use some legacy systems, which are not necessarily
written up to high-end Avalon standards... SingleThreaded servlets
should be considered as a way to integrate such things.


> > > BTW, The Fortress
> > > container has a much shorter release() cycle because it handles
> > > the logic asyncronously.  It may take a little longer getting the
> > > instance into the pool, but it doesn't affect the critical path.
> >
> > This will have to be benchmarked then.
> 
> There is a performance benchmark that uses ECM/Fortress in Fortress's
> test code.  It has been compared.

Cool.

Vadim



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Vadim Gritsenko [mailto:vadim.gritsenko@verizon.net] 
> 
> 
> And work itself will be done in XMLSource/XMLPipeline/XMLSink. I got
> that part. Hope performance will not be sacrificed by this move (you
> will be new()ing this objects all the time)

Modern JVMs have better GC policies, and is quicker at handling trivial
objects.  You can still do Pooling, but it is handled by the
GeneratorManager.


> > The new way would probably add a GeneratorManager for this purpose.
> > However,
> > the artifact returned is preinitialized with everything it 
> needs.  The
> > GeneratorManager, TransformerManager, and SerializerManager can all
> take
> > care
> > of usage semantics if it handles pooled items.
> 
> How they differ from ComponentSelector?


More focused management policies, type safety (no more casting), and
the "setUp()" method becomes the query method.  This allows more
specific criteria for Generator types.

Furthermore, a GeneratorManager can declare its own semantics.  If you
want the release() method there, then there are no issues conflicting
with overall CM design.


> 
> I think discussion here was carried away from topic... Architecture of
> future Cocoon should be discussed separately. I was trying only to
> clarify how container will handle absence of the release() method.

The GeneratorManager would handle the release() method, or it would
declare its semantics for use.

Component use should not be a function of component lookup.


> > > > As the ContentHandler.endDocument() is called on each item,
> > > > they are automatically returned to their pools.
> > >
> > > Two issues on this one:
> > >
> > > 1. endDocument might be never be called. I can discard
> > > component after evaluating its cache ID or cache validity.
> > >
> > > 2. endDocument does not necessarily indicates that I'm done
> > > with this component.
> 
> What about these points?

By implementing the GeneratorManager, et. al. the CM doesn't care
about it, and component GC is not necessary.  The XMLSource can be
released to the GeneratorManager.


> > > Simple example: you are using serializer
> > > to serialize xml fragment 100 times. It would be logical to
> > > make a loop:
> > >
> > > serialier = lookup();
> > > for(;;){
> > >   serializer.setDestination();
> > >   serializer.startDocument();
> > >   ...
> > >   serializer.endDocument();
> > > }
> > >
> > 
> > Wrong application.  It is a Transformers job to modify the XML
> > so that you have an XML fragment repeating 100 times. 
> 
> This code *is* in transformer. Consider input XML:
> 
> <x:repeat times="100">
>   <x:write>
> 
>     ... some xml goes here ...
> 
>   </x:write>
> </x:repeat>

That is another design problem.  It is not the Transformer's job.
It is separate from the CM interface issue.


> > The
> > Serializer should only opperate on the XML given to it.
> 
> It is given with the XML, and operates only on it.
> 
> 
> > A serializer should _*never*_ modify the content of the XML.  It
> > can only modify the binary stream's representation of it.
> 
> It does not. I guess you did not understand my thought. Point is:
> endDocument is no indication to component manager that this 
> component is
> free.

Forget GC for now.  Can you see how it can be done with a
GeneratorManager?


> > > > As to timeouts, we can use one policy for the container 
> type.  For
> > > > example, Cocoon would benefit from a request based approach.
> > >
> > > What if processing continues after sending response?
> > > I.e., after endDocument() on serializer, some work is done in
> > > transformer? Like invoking other serializer?
> > 
> > Then you have broken Cocoon's design.  A Transformer does not invoke
> > serializer. 
> 
> Transformers now invoke: Source, LDAP connections, SQL connections,
> XML:DB collections, files, Loggers... What makes serializer 
> so special?
> Why code, say, XML->PDF code again and not reuse? Or
> SAX->XML-in-a-String?

What about the sitemap handling the separate sinks, you know the
pipeline multiplexer/demultiplexer concept?


> > Ever.  It is the Sitemap's responsibility to manage all
> > pipelines--whether they have branched or not.  Once all 
> processing for
> > a request is done--and the sitemap or at least the Cocoon container
> > knows this unequivicably--then it can reclaim the components.
> 
>     Exactly!
> 
> Cocoon *container* knows! But this is *not* indicated by some
> endDocument() on some (intermediate) component in the middle of
> processing!

Which was my original point.  The endDocument() was an example of
another possibility.  IF you want to extend the SAX spec that says
a contenthandler  is done when endDocument() is called and it
can free resources, then that's on you.

> 
> But when and how you collect and return to the pool components used
> during processing? Right now this is done as soon as component is not
> needed. If you to do this only once and only after *whole* 
> processing is
> finished you are bound to hold (critical) resources longer then
> necessary.

That is a price of GC systems.  However, you can make critical resources
less prone to extended resource holding by providing something akin to
the DataSourceComponent, even if you make the release() method part of
the managing component.


> > > > Other
> > > > containers may have to use a timeout based approach.  Its up to
> the
> > > > container.  Are timeouts sufficient?  No.  Does it add 
> additional
> > > > complexity for the container? Yes.  Does it help the developer?
> > > > absolutely.
> > >
> > > There are situations when transaction takes hours to process
> > > (I do not mean DB transaction here). How this will happen?
> > 
> > Wow.  Hours? Then you need to think of a different way of handling
> that
> > transaction. That is a deeper design issue that needs 
> serious thought
> > for that application.
> 
> Simple example: print invoices at the end of the month. You don't want
> to hold lots of critical resources during, say, 8 hour process in
> top-level component which performs this, right?

Yes, but you wouldn't necessarily have your production (i.e. web) system
doing
this either.  It would be an offline process kicked off from the
commandline
(chron daemon) or something else along those lines.  It is an
asynchronous
process.  Smarter component design will allow you to avoid necessary
pooling,
causing fewer resources to be used, less resource contention, and
ultimately
higher performance.


> > > > > But component state is lost in the "refresh". Meaning
> > > > > that for a SAX
> > > > > transformer or *any other component with state* you have
> > > > > screwed up
> > > > > the processing. (So don't allow components with state,
> > > > > then - well,
> > > > > then they are all ThreadSafe and we do not need
> > > > > pools.)
> > > >
> > > > See above.  The Cocoon pipeline component interfaces are really
> > > > screwed up in this respect.  A component's state should be
> > > > sufficient
> > > > per thread.
> > >
> > > Thread can require several components of the same type to do
> > > its work. How this will be handled?
> > 
> > Use the ***Manager approach above.  If you need a unique instance of
> > a component for each lookup, then there is probably something wrong
> > in your design.
> 
> J2EE has REQUIRES_NEW transaction management attribute for the EJB
> method. If you have such methods (is it considered wrong design?), all
> required for this method TxResource-s should be looked up, 
> thus you will
> have more then one instance of a component.

J2EE also allowed you to declare Servlets as single use (not one
instance
per thread or sharing an instance among threads)--does that make it
correct
design?  It was a serious bottleneck allowing a Q&D hack.

> > BTW, The Fortress
> > container has a much shorter release() cycle because it handles
> > the logic asyncronously.  It may take a little longer getting the
> > instance into the pool, but it doesn't affect the critical path.
> 
> This will have to be benchmarked then.

There is a performance benchmark that uses ECM/Fortress in Fortress's
test code.  It has been compared.


> > However, if a Transformer directly uses a Serializer then something
> > is wrong.  That was never the intention of the Cocoon component
> > model.
> 
> Even if it is wrong about using Serializer from Transformer. How about
> using Serializer from some other component, not Cocoon component?


Design how your system is supposed to interact--then enforce it.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Vadim Gritsenko [mailto:vadim.gritsenko@verizon.net] 
> 
> 
> And work itself will be done in XMLSource/XMLPipeline/XMLSink. I got
> that part. Hope performance will not be sacrificed by this move (you
> will be new()ing this objects all the time)

Modern JVMs have better GC policies, and is quicker at handling trivial
objects.  You can still do Pooling, but it is handled by the
GeneratorManager.


> > The new way would probably add a GeneratorManager for this purpose.
> > However,
> > the artifact returned is preinitialized with everything it 
> needs.  The
> > GeneratorManager, TransformerManager, and SerializerManager can all
> take
> > care
> > of usage semantics if it handles pooled items.
> 
> How they differ from ComponentSelector?


More focused management policies, type safety (no more casting), and
the "setUp()" method becomes the query method.  This allows more
specific criteria for Generator types.

Furthermore, a GeneratorManager can declare its own semantics.  If you
want the release() method there, then there are no issues conflicting
with overall CM design.


> 
> I think discussion here was carried away from topic... Architecture of
> future Cocoon should be discussed separately. I was trying only to
> clarify how container will handle absence of the release() method.

The GeneratorManager would handle the release() method, or it would
declare its semantics for use.

Component use should not be a function of component lookup.


> > > > As the ContentHandler.endDocument() is called on each item,
> > > > they are automatically returned to their pools.
> > >
> > > Two issues on this one:
> > >
> > > 1. endDocument might be never be called. I can discard
> > > component after evaluating its cache ID or cache validity.
> > >
> > > 2. endDocument does not necessarily indicates that I'm done
> > > with this component.
> 
> What about these points?

By implementing the GeneratorManager, et. al. the CM doesn't care
about it, and component GC is not necessary.  The XMLSource can be
released to the GeneratorManager.


> > > Simple example: you are using serializer
> > > to serialize xml fragment 100 times. It would be logical to
> > > make a loop:
> > >
> > > serialier = lookup();
> > > for(;;){
> > >   serializer.setDestination();
> > >   serializer.startDocument();
> > >   ...
> > >   serializer.endDocument();
> > > }
> > >
> > 
> > Wrong application.  It is a Transformers job to modify the XML
> > so that you have an XML fragment repeating 100 times. 
> 
> This code *is* in transformer. Consider input XML:
> 
> <x:repeat times="100">
>   <x:write>
> 
>     ... some xml goes here ...
> 
>   </x:write>
> </x:repeat>

That is another design problem.  It is not the Transformer's job.
It is separate from the CM interface issue.


> > The
> > Serializer should only opperate on the XML given to it.
> 
> It is given with the XML, and operates only on it.
> 
> 
> > A serializer should _*never*_ modify the content of the XML.  It
> > can only modify the binary stream's representation of it.
> 
> It does not. I guess you did not understand my thought. Point is:
> endDocument is no indication to component manager that this 
> component is
> free.

Forget GC for now.  Can you see how it can be done with a
GeneratorManager?


> > > > As to timeouts, we can use one policy for the container 
> type.  For
> > > > example, Cocoon would benefit from a request based approach.
> > >
> > > What if processing continues after sending response?
> > > I.e., after endDocument() on serializer, some work is done in
> > > transformer? Like invoking other serializer?
> > 
> > Then you have broken Cocoon's design.  A Transformer does not invoke
> > serializer. 
> 
> Transformers now invoke: Source, LDAP connections, SQL connections,
> XML:DB collections, files, Loggers... What makes serializer 
> so special?
> Why code, say, XML->PDF code again and not reuse? Or
> SAX->XML-in-a-String?

What about the sitemap handling the separate sinks, you know the
pipeline multiplexer/demultiplexer concept?


> > Ever.  It is the Sitemap's responsibility to manage all
> > pipelines--whether they have branched or not.  Once all 
> processing for
> > a request is done--and the sitemap or at least the Cocoon container
> > knows this unequivicably--then it can reclaim the components.
> 
>     Exactly!
> 
> Cocoon *container* knows! But this is *not* indicated by some
> endDocument() on some (intermediate) component in the middle of
> processing!

Which was my original point.  The endDocument() was an example of
another possibility.  IF you want to extend the SAX spec that says
a contenthandler  is done when endDocument() is called and it
can free resources, then that's on you.

> 
> But when and how you collect and return to the pool components used
> during processing? Right now this is done as soon as component is not
> needed. If you to do this only once and only after *whole* 
> processing is
> finished you are bound to hold (critical) resources longer then
> necessary.

That is a price of GC systems.  However, you can make critical resources
less prone to extended resource holding by providing something akin to
the DataSourceComponent, even if you make the release() method part of
the managing component.


> > > > Other
> > > > containers may have to use a timeout based approach.  Its up to
> the
> > > > container.  Are timeouts sufficient?  No.  Does it add 
> additional
> > > > complexity for the container? Yes.  Does it help the developer?
> > > > absolutely.
> > >
> > > There are situations when transaction takes hours to process
> > > (I do not mean DB transaction here). How this will happen?
> > 
> > Wow.  Hours? Then you need to think of a different way of handling
> that
> > transaction. That is a deeper design issue that needs 
> serious thought
> > for that application.
> 
> Simple example: print invoices at the end of the month. You don't want
> to hold lots of critical resources during, say, 8 hour process in
> top-level component which performs this, right?

Yes, but you wouldn't necessarily have your production (i.e. web) system
doing
this either.  It would be an offline process kicked off from the
commandline
(chron daemon) or something else along those lines.  It is an
asynchronous
process.  Smarter component design will allow you to avoid necessary
pooling,
causing fewer resources to be used, less resource contention, and
ultimately
higher performance.


> > > > > But component state is lost in the "refresh". Meaning
> > > > > that for a SAX
> > > > > transformer or *any other component with state* you have
> > > > > screwed up
> > > > > the processing. (So don't allow components with state,
> > > > > then - well,
> > > > > then they are all ThreadSafe and we do not need
> > > > > pools.)
> > > >
> > > > See above.  The Cocoon pipeline component interfaces are really
> > > > screwed up in this respect.  A component's state should be
> > > > sufficient
> > > > per thread.
> > >
> > > Thread can require several components of the same type to do
> > > its work. How this will be handled?
> > 
> > Use the ***Manager approach above.  If you need a unique instance of
> > a component for each lookup, then there is probably something wrong
> > in your design.
> 
> J2EE has REQUIRES_NEW transaction management attribute for the EJB
> method. If you have such methods (is it considered wrong design?), all
> required for this method TxResource-s should be looked up, 
> thus you will
> have more then one instance of a component.

J2EE also allowed you to declare Servlets as single use (not one
instance
per thread or sharing an instance among threads)--does that make it
correct
design?  It was a serious bottleneck allowing a Q&D hack.

> > BTW, The Fortress
> > container has a much shorter release() cycle because it handles
> > the logic asyncronously.  It may take a little longer getting the
> > instance into the pool, but it doesn't affect the critical path.
> 
> This will have to be benchmarked then.

There is a performance benchmark that uses ECM/Fortress in Fortress's
test code.  It has been compared.


> > However, if a Transformer directly uses a Serializer then something
> > is wrong.  That was never the intention of the Cocoon component
> > model.
> 
> Even if it is wrong about using Serializer from Transformer. How about
> using Serializer from some other component, not Cocoon component?


Design how your system is supposed to interact--then enforce it.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Berin Loritsch [mailto:bloritsch@apache.org]
> 
> > From: Vadim Gritsenko [mailto:vadim.gritsenko@verizon.net]
> >
> > > From: Berin Loritsch [mailto:bloritsch@apache.org]
> >
> > <snip-a-lot/>
> >
> > ASSUMPTION:
> >
> >   Poolable component is a component with high instantiation
> > cost and state thus it can not be used in several threads
> > simultaneously.
> >
> 
> Don't forget Per-Thread policy (not in ECM, but in new Fortress
> package).  That instantiates one instance of a component per
> thread, and you don't need pooling semantics to do it.

Mmm... This can help in some situations...


> So that assumption is too broad.
> 
> Poolable components are for components that must be unique to
> each lookup.  It is these types of components that should be
> changed.  The Transformer is a perfect example of that.

If we to remove ContentHandler interface from Transformer it will become
ThreadSafe, so Per-Thread policy won't be used here.


> > > However, the interfaces for the Cocoon pipeline components
> > > are broken.
> > > A Generator should return an XMLSource, a Transformer
> > > should return an
> > > interface that merges XMLSource and ContentHandler, and a
> > > Serializer should return a ContentHandler.
> >
> > Right now Transformers are poolable. They have a state and they are
> > (supposedly) heavy to new().
> 
> Some of them are.  Their heaviness comes from the lifecycle they
> must go through before they are ready to be used.  Some trivial
> Transformers that do not need context information, or to lookup
> other components, or to be configured are better off new()ing
> every time.

Ok.


> > If you to change Transformer interface to return only
> > XMLSource/ContentHandler, all the logic and state Transformer
> > has moves into this XMLSource.
> 
> The state information moves into an artifact of the runtime
> system.  This is as it should be.  We can query the component
> for a unique instance of the XMLPipeline (merging of XMLSource
> and ContentHander)--opening the door for other types of performance
> enhancing opportunities.  Once the XSLT transformer has generated
> the template, it can use a cached version of it--and the logic
> makes sense.  Consider this use case:
> 
> --------Current State----------
> 
> generator.setup(....); // finds out the source info, etc...
> transformer.setup(....); // finds out the source info, etc...
> serializer.setup(....);
> 
> transformer.setContentHandler( serializer );
> generator.setContentHandler( transformer );
> generator.execute();
> 
> -------New Way-----------
> 
> XMLSource source = generator.getSource( type, .... ); // can cache at
> this point
> XMLPipeline pipe = transformer.getPipeline ( type, .... ); // can
cache
> at this point
> ContentHandler sink = serializer.getSink( type, .... ); // can cache
at
> this point..if necessary
> 
> source.setContentHandler( pipe );
> pipe.setConentHandler( sink );
> source.execute();
> 
> -------------------------
> 
> It also helps in assembling the pipeline dynamically, with fewer
> lookups.
> 
> The fact that we work with fairly generic types allows us the ability
> to take advantage of generative programming such as using BCEL to
> generate
> a class that spits out SAX events (kind of like XSP but better)--and
> have that done by the caching system.  The Generator component's
> responsibility
> then becomes how to manage these artifacts rather than how to actually
> do the work.

And work itself will be done in XMLSource/XMLPipeline/XMLSink. I got
that part. Hope performance will not be sacrificed by this move (you
will be new()ing this objects all the time)


> The new way would probably add a GeneratorManager for this purpose.
> However,
> the artifact returned is preinitialized with everything it needs.  The
> GeneratorManager, TransformerManager, and SerializerManager can all
take
> care
> of usage semantics if it handles pooled items.

How they differ from ComponentSelector?


> Otherwise stated, it would be *more* correct to return artifacts to a
> specific
> manager than it would be to return it to a lookup mechanism.  What we
> want to
> restore is the separation of concerns for the lookup mechanism.  The
CM
> was
> only designed to be a lookup mechanism--not a container.
> 
> >
> > Thus, XMLSource becomes heavy and Transformer light.
> > Obviously, Transformer becomes ThreadSafe (which is good) and
> > XMLSource must be made Poolable (its heavy, it is stateful).
> 
> 
> Not necessarily--there are other possibilities for optimization
> at a systemic level that would not otherwise present itself.
> 
> 
> > Instead of having one component we ended up with two. Please
> > tell me I see things wrongly.
> >
> > <snip what="simple pipeline"/>
> 
> You end up with one management component, and artifacts it returns.
> Those artifacts can be cached results, compiled XML streams, or
> C2 Generators, etc.  We are no longer limited by our architecture.
> We can have more intelligent operations on the pipeline components.

I think discussion here was carried away from topic... Architecture of
future Cocoon should be discussed separately. I was trying only to
clarify how container will handle absence of the release() method.


> > > As the ContentHandler.endDocument() is called on each item,
> > > they are automatically returned to their pools.
> >
> > Two issues on this one:
> >
> > 1. endDocument might be never be called. I can discard
> > component after evaluating its cache ID or cache validity.
> >
> > 2. endDocument does not necessarily indicates that I'm done
> > with this component.

What about these points?


> > Simple example: you are using serializer
> > to serialize xml fragment 100 times. It would be logical to
> > make a loop:
> >
> > serialier = lookup();
> > for(;;){
> >   serializer.setDestination();
> >   serializer.startDocument();
> >   ...
> >   serializer.endDocument();
> > }
> >
> 
> Wrong application.  It is a Transformers job to modify the XML
> so that you have an XML fragment repeating 100 times. 

This code *is* in transformer. Consider input XML:

<x:repeat times="100">
  <x:write>

    ... some xml goes here ...

  </x:write>
</x:repeat>


> The
> Serializer should only opperate on the XML given to it.

It is given with the XML, and operates only on it.


> A serializer should _*never*_ modify the content of the XML.  It
> can only modify the binary stream's representation of it.

It does not. I guess you did not understand my thought. Point is:
endDocument is no indication to component manager that this component is
free.


> > > As to timeouts, we can use one policy for the container type.  For
> > > example, Cocoon would benefit from a request based approach.
> >
> > What if processing continues after sending response?
> > I.e., after endDocument() on serializer, some work is done in
> > transformer? Like invoking other serializer?
> 
> Then you have broken Cocoon's design.  A Transformer does not invoke
> serializer. 

Transformers now invoke: Source, LDAP connections, SQL connections,
XML:DB collections, files, Loggers... What makes serializer so special?
Why code, say, XML->PDF code again and not reuse? Or
SAX->XML-in-a-String?


> Ever.  It is the Sitemap's responsibility to manage all
> pipelines--whether they have branched or not.  Once all processing for
> a request is done--and the sitemap or at least the Cocoon container
> knows this unequivicably--then it can reclaim the components.

    Exactly!

Cocoon *container* knows! But this is *not* indicated by some
endDocument() on some (intermediate) component in the middle of
processing!

But when and how you collect and return to the pool components used
during processing? Right now this is done as soon as component is not
needed. If you to do this only once and only after *whole* processing is
finished you are bound to hold (critical) resources longer then
necessary.


> > > Other
> > > containers may have to use a timeout based approach.  Its up to
the
> > > container.  Are timeouts sufficient?  No.  Does it add additional
> > > complexity for the container? Yes.  Does it help the developer?
> > > absolutely.
> >
> > There are situations when transaction takes hours to process
> > (I do not mean DB transaction here). How this will happen?
> 
> Wow.  Hours? Then you need to think of a different way of handling
that
> transaction. That is a deeper design issue that needs serious thought
> for that application.

Simple example: print invoices at the end of the month. You don't want
to hold lots of critical resources during, say, 8 hour process in
top-level component which performs this, right?


> > > > But component state is lost in the "refresh". Meaning
> > > > that for a SAX
> > > > transformer or *any other component with state* you have
> > > > screwed up
> > > > the processing. (So don't allow components with state,
> > > > then - well,
> > > > then they are all ThreadSafe and we do not need
> > > > pools.)
> > >
> > > See above.  The Cocoon pipeline component interfaces are really
> > > screwed up in this respect.  A component's state should be
> > > sufficient
> > > per thread.
> >
> > Thread can require several components of the same type to do
> > its work. How this will be handled?
> 
> Use the ***Manager approach above.  If you need a unique instance of
> a component for each lookup, then there is probably something wrong
> in your design.

J2EE has REQUIRES_NEW transaction management attribute for the EJB
method. If you have such methods (is it considered wrong design?), all
required for this method TxResource-s should be looked up, thus you will
have more then one instance of a component.


> > > Anything that is more granular than that needs a
> > > different treatment.
> >
> > What could it be?
> 
> A **Manager approach outlined above.
> 
> 
> > > > The basis of GC is that you can unambiguously tell when
> > > > an object is
> > > > no longer used - when it can not possibly be used. The
> > > > speedups we
> > > > have in pooling is due to explicitly telling the
> > > > container that this
> > > > object can be reclaimed, thus keeping the object count low.
> > >
> > > In Cocoon we have the advantage of knowing that.  A
> > > pipeline component
> > > cannot possibly be used past the processing of a request.
> >
> > Some transformers use instance of serializers to do its work.
> > It could be looked up on startup and returned on shutdown (to
> > speedup processing
> > - right now manager.release() is quite expensive operation),
> > and will not depend on request/response cycles.
> 
> :) And now you are getting why we need to design our components
> so that we do not need to release() them.

Lookup/release is slow now only because it tracks all the components
looked up by this component - all these scans of ArrayList's slowing
down things.


> BTW, The Fortress
> container has a much shorter release() cycle because it handles
> the logic asyncronously.  It may take a little longer getting the
> instance into the pool, but it doesn't affect the critical path.

This will have to be benchmarked then.


> However, if a Transformer directly uses a Serializer then something
> is wrong.  That was never the intention of the Cocoon component
> model.

Even if it is wrong about using Serializer from Transformer. How about
using Serializer from some other component, not Cocoon component?

Vadim



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Berin Loritsch [mailto:bloritsch@apache.org]
> 
> > From: Vadim Gritsenko [mailto:vadim.gritsenko@verizon.net]
> >
> > > From: Berin Loritsch [mailto:bloritsch@apache.org]
> >
> > <snip-a-lot/>
> >
> > ASSUMPTION:
> >
> >   Poolable component is a component with high instantiation
> > cost and state thus it can not be used in several threads
> > simultaneously.
> >
> 
> Don't forget Per-Thread policy (not in ECM, but in new Fortress
> package).  That instantiates one instance of a component per
> thread, and you don't need pooling semantics to do it.

Mmm... This can help in some situations...


> So that assumption is too broad.
> 
> Poolable components are for components that must be unique to
> each lookup.  It is these types of components that should be
> changed.  The Transformer is a perfect example of that.

If we to remove ContentHandler interface from Transformer it will become
ThreadSafe, so Per-Thread policy won't be used here.


> > > However, the interfaces for the Cocoon pipeline components
> > > are broken.
> > > A Generator should return an XMLSource, a Transformer
> > > should return an
> > > interface that merges XMLSource and ContentHandler, and a
> > > Serializer should return a ContentHandler.
> >
> > Right now Transformers are poolable. They have a state and they are
> > (supposedly) heavy to new().
> 
> Some of them are.  Their heaviness comes from the lifecycle they
> must go through before they are ready to be used.  Some trivial
> Transformers that do not need context information, or to lookup
> other components, or to be configured are better off new()ing
> every time.

Ok.


> > If you to change Transformer interface to return only
> > XMLSource/ContentHandler, all the logic and state Transformer
> > has moves into this XMLSource.
> 
> The state information moves into an artifact of the runtime
> system.  This is as it should be.  We can query the component
> for a unique instance of the XMLPipeline (merging of XMLSource
> and ContentHander)--opening the door for other types of performance
> enhancing opportunities.  Once the XSLT transformer has generated
> the template, it can use a cached version of it--and the logic
> makes sense.  Consider this use case:
> 
> --------Current State----------
> 
> generator.setup(....); // finds out the source info, etc...
> transformer.setup(....); // finds out the source info, etc...
> serializer.setup(....);
> 
> transformer.setContentHandler( serializer );
> generator.setContentHandler( transformer );
> generator.execute();
> 
> -------New Way-----------
> 
> XMLSource source = generator.getSource( type, .... ); // can cache at
> this point
> XMLPipeline pipe = transformer.getPipeline ( type, .... ); // can
cache
> at this point
> ContentHandler sink = serializer.getSink( type, .... ); // can cache
at
> this point..if necessary
> 
> source.setContentHandler( pipe );
> pipe.setConentHandler( sink );
> source.execute();
> 
> -------------------------
> 
> It also helps in assembling the pipeline dynamically, with fewer
> lookups.
> 
> The fact that we work with fairly generic types allows us the ability
> to take advantage of generative programming such as using BCEL to
> generate
> a class that spits out SAX events (kind of like XSP but better)--and
> have that done by the caching system.  The Generator component's
> responsibility
> then becomes how to manage these artifacts rather than how to actually
> do the work.

And work itself will be done in XMLSource/XMLPipeline/XMLSink. I got
that part. Hope performance will not be sacrificed by this move (you
will be new()ing this objects all the time)


> The new way would probably add a GeneratorManager for this purpose.
> However,
> the artifact returned is preinitialized with everything it needs.  The
> GeneratorManager, TransformerManager, and SerializerManager can all
take
> care
> of usage semantics if it handles pooled items.

How they differ from ComponentSelector?


> Otherwise stated, it would be *more* correct to return artifacts to a
> specific
> manager than it would be to return it to a lookup mechanism.  What we
> want to
> restore is the separation of concerns for the lookup mechanism.  The
CM
> was
> only designed to be a lookup mechanism--not a container.
> 
> >
> > Thus, XMLSource becomes heavy and Transformer light.
> > Obviously, Transformer becomes ThreadSafe (which is good) and
> > XMLSource must be made Poolable (its heavy, it is stateful).
> 
> 
> Not necessarily--there are other possibilities for optimization
> at a systemic level that would not otherwise present itself.
> 
> 
> > Instead of having one component we ended up with two. Please
> > tell me I see things wrongly.
> >
> > <snip what="simple pipeline"/>
> 
> You end up with one management component, and artifacts it returns.
> Those artifacts can be cached results, compiled XML streams, or
> C2 Generators, etc.  We are no longer limited by our architecture.
> We can have more intelligent operations on the pipeline components.

I think discussion here was carried away from topic... Architecture of
future Cocoon should be discussed separately. I was trying only to
clarify how container will handle absence of the release() method.


> > > As the ContentHandler.endDocument() is called on each item,
> > > they are automatically returned to their pools.
> >
> > Two issues on this one:
> >
> > 1. endDocument might be never be called. I can discard
> > component after evaluating its cache ID or cache validity.
> >
> > 2. endDocument does not necessarily indicates that I'm done
> > with this component.

What about these points?


> > Simple example: you are using serializer
> > to serialize xml fragment 100 times. It would be logical to
> > make a loop:
> >
> > serialier = lookup();
> > for(;;){
> >   serializer.setDestination();
> >   serializer.startDocument();
> >   ...
> >   serializer.endDocument();
> > }
> >
> 
> Wrong application.  It is a Transformers job to modify the XML
> so that you have an XML fragment repeating 100 times. 

This code *is* in transformer. Consider input XML:

<x:repeat times="100">
  <x:write>

    ... some xml goes here ...

  </x:write>
</x:repeat>


> The
> Serializer should only opperate on the XML given to it.

It is given with the XML, and operates only on it.


> A serializer should _*never*_ modify the content of the XML.  It
> can only modify the binary stream's representation of it.

It does not. I guess you did not understand my thought. Point is:
endDocument is no indication to component manager that this component is
free.


> > > As to timeouts, we can use one policy for the container type.  For
> > > example, Cocoon would benefit from a request based approach.
> >
> > What if processing continues after sending response?
> > I.e., after endDocument() on serializer, some work is done in
> > transformer? Like invoking other serializer?
> 
> Then you have broken Cocoon's design.  A Transformer does not invoke
> serializer. 

Transformers now invoke: Source, LDAP connections, SQL connections,
XML:DB collections, files, Loggers... What makes serializer so special?
Why code, say, XML->PDF code again and not reuse? Or
SAX->XML-in-a-String?


> Ever.  It is the Sitemap's responsibility to manage all
> pipelines--whether they have branched or not.  Once all processing for
> a request is done--and the sitemap or at least the Cocoon container
> knows this unequivicably--then it can reclaim the components.

    Exactly!

Cocoon *container* knows! But this is *not* indicated by some
endDocument() on some (intermediate) component in the middle of
processing!

But when and how you collect and return to the pool components used
during processing? Right now this is done as soon as component is not
needed. If you to do this only once and only after *whole* processing is
finished you are bound to hold (critical) resources longer then
necessary.


> > > Other
> > > containers may have to use a timeout based approach.  Its up to
the
> > > container.  Are timeouts sufficient?  No.  Does it add additional
> > > complexity for the container? Yes.  Does it help the developer?
> > > absolutely.
> >
> > There are situations when transaction takes hours to process
> > (I do not mean DB transaction here). How this will happen?
> 
> Wow.  Hours? Then you need to think of a different way of handling
that
> transaction. That is a deeper design issue that needs serious thought
> for that application.

Simple example: print invoices at the end of the month. You don't want
to hold lots of critical resources during, say, 8 hour process in
top-level component which performs this, right?


> > > > But component state is lost in the "refresh". Meaning
> > > > that for a SAX
> > > > transformer or *any other component with state* you have
> > > > screwed up
> > > > the processing. (So don't allow components with state,
> > > > then - well,
> > > > then they are all ThreadSafe and we do not need
> > > > pools.)
> > >
> > > See above.  The Cocoon pipeline component interfaces are really
> > > screwed up in this respect.  A component's state should be
> > > sufficient
> > > per thread.
> >
> > Thread can require several components of the same type to do
> > its work. How this will be handled?
> 
> Use the ***Manager approach above.  If you need a unique instance of
> a component for each lookup, then there is probably something wrong
> in your design.

J2EE has REQUIRES_NEW transaction management attribute for the EJB
method. If you have such methods (is it considered wrong design?), all
required for this method TxResource-s should be looked up, thus you will
have more then one instance of a component.


> > > Anything that is more granular than that needs a
> > > different treatment.
> >
> > What could it be?
> 
> A **Manager approach outlined above.
> 
> 
> > > > The basis of GC is that you can unambiguously tell when
> > > > an object is
> > > > no longer used - when it can not possibly be used. The
> > > > speedups we
> > > > have in pooling is due to explicitly telling the
> > > > container that this
> > > > object can be reclaimed, thus keeping the object count low.
> > >
> > > In Cocoon we have the advantage of knowing that.  A
> > > pipeline component
> > > cannot possibly be used past the processing of a request.
> >
> > Some transformers use instance of serializers to do its work.
> > It could be looked up on startup and returned on shutdown (to
> > speedup processing
> > - right now manager.release() is quite expensive operation),
> > and will not depend on request/response cycles.
> 
> :) And now you are getting why we need to design our components
> so that we do not need to release() them.

Lookup/release is slow now only because it tracks all the components
looked up by this component - all these scans of ArrayList's slowing
down things.


> BTW, The Fortress
> container has a much shorter release() cycle because it handles
> the logic asyncronously.  It may take a little longer getting the
> instance into the pool, but it doesn't affect the critical path.

This will have to be benchmarked then.


> However, if a Transformer directly uses a Serializer then something
> is wrong.  That was never the intention of the Cocoon component
> model.

Even if it is wrong about using Serializer from Transformer. How about
using Serializer from some other component, not Cocoon component?

Vadim



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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Vadim Gritsenko [mailto:vadim.gritsenko@verizon.net] 
> 
> > From: Berin Loritsch [mailto:bloritsch@apache.org]
> 
> <snip-a-lot/>
> 
> ASSUMPTION:
> 
>   Poolable component is a component with high instantiation 
> cost and state thus it can not be used in several threads 
> simultaneously.
> 

Don't forget Per-Thread policy (not in ECM, but in new Fortress
package).  That instantiates one instance of a component per
thread, and you don't need pooling semantics to do it.

So that assumption is too broad.

Poolable components are for components that must be unique to
each lookup.  It is these types of components that should be
changed.  The Transformer is a perfect example of that.


> > However, the interfaces for the Cocoon pipeline components 
> are broken. 
> > A Generator should return an XMLSource, a Transformer 
> should return an 
> > interface that merges XMLSource and ContentHandler, and a
> Serializer
> > should return a ContentHandler.
> 
> Right now Transformers are poolable. They have a state and they are
> (supposedly) heavy to new().

Some of them are.  Their heaviness comes from the lifecycle they
must go through before they are ready to be used.  Some trivial
Transformers that do not need context information, or to lookup
other components, or to be configured are better off new()ing
every time.


> If you to change Transformer interface to return only 
> XMLSource/ContentHandler, all the logic and state Transformer 
> has moves into this XMLSource.

The state information moves into an artifact of the runtime
system.  This is as it should be.  We can query the component
for a unique instance of the XMLPipeline (merging of XMLSource
and ContentHander)--opening the door for other types of performance
enhancing opportunities.  Once the XSLT transformer has generated
the template, it can use a cached version of it--and the logic
makes sense.  Consider this use case:

--------Current State----------

generator.setup(....); // finds out the source info, etc...
transformer.setup(....); // finds out the source info, etc...
serializer.setup(....);

transformer.setContentHandler( serializer );
generator.setContentHandler( transformer );
generator.execute();

-------New Way-----------

XMLSource source = generator.getSource( type, .... ); // can cache at
this point
XMLPipeline pipe = transformer.getPipeline ( type, .... ); // can cache
at this point
ContentHandler sink = serializer.getSink( type, .... ); // can cache at
this point..if necessary

source.setContentHandler( pipe );
pipe.setConentHandler( sink );
source.execute();

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

It also helps in assembling the pipeline dynamically, with fewer
lookups.

The fact that we work with fairly generic types allows us the ability
to take advantage of generative programming such as using BCEL to
generate
a class that spits out SAX events (kind of like XSP but better)--and
have that done by the caching system.  The Generator component's
responsibility
then becomes how to manage these artifacts rather than how to actually
do the work.

The new way would probably add a GeneratorManager for this purpose.
However,
the artifact returned is preinitialized with everything it needs.  The
GeneratorManager, TransformerManager, and SerializerManager can all take
care
of usage semantics if it handles pooled items.

Otherwise stated, it would be *more* correct to return artifacts to a
specific
manager than it would be to return it to a lookup mechanism.  What we
want to
restore is the separation of concerns for the lookup mechanism.  The CM
was
only designed to be a lookup mechanism--not a container.

> 
> Thus, XMLSource becomes heavy and Transformer light. 
> Obviously, Transformer becomes ThreadSafe (which is good) and 
> XMLSource must be made Poolable (its heavy, it is stateful).


Not necessarily--there are other possibilities for optimization
at a systemic level that would not otherwise present itself.


> Instead of having one component we ended up with two. Please 
> tell me I see things wrongly.
> 
> <snip what="simple pipeline"/>

You end up with one management component, and artifacts it returns.
Those artifacts can be cached results, compiled XML streams, or
C2 Generators, etc.  We are no longer limited by our architecture.
We can have more intelligent operations on the pipeline components.



> > As the ContentHandler.endDocument() is called on each item, 
> they are 
> > automatically returned to their pools.
> 
> Two issues on this one:
> 
> 1. endDocument might be never be called. I can discard 
> component after evaluating its cache ID or cache validity.
> 
> 2. endDocument does not necessarily indicates that I'm done 
> with this component. Simple example: you are using serializer 
> to serialize xml fragment 100 times. It would be logical to 
> make a loop:
> 
> serialier = lookup();
> for(;;){
>   serializer.setDestination();
>   serializer.startDocument();
>   ...
>   serializer.endDocument();
> }
> 

Wrong application.  It is a Transformers job to modify the XML
so that you have an XML fragment repeating 100 times.  The
Serializer should only opperate on the XML given to it.

A serializer should _*never*_ modify the content of the XML.  It
can only modify the binary stream's representation of it.


> > As to timeouts, we can use one policy for the container type.  For 
> > example, Cocoon would benefit from a request based approach.
> 
> What if processing continues after sending response?
> I.e., after endDocument() on serializer, some work is done in 
> transformer? Like invoking other serializer?

Then you have broken Cocoon's design.  A Transformer does not invoke
serializer.  Ever.  It is the Sitemap's responsibility to manage all
pipelines--whether they have branched or not.  Once all processing for
a request is done--and the sitemap or at least the Cocoon container
knows this unequivicably--then it can reclaim the components.


> > Other
> > containers may have to use a timeout based approach.  Its up to the 
> > container.  Are timeouts sufficient?  No.  Does it add additional 
> > complexity for the container? Yes.  Does it help the developer? 
> > absolutely.
> 
> There are situations when transaction takes hours to process 
> (I do not mean DB transaction here). How this will happen?

Wow.  Hours?  Then you need to think of a different way of handling that
transaction.  That is a deeper design issue that needs serious thought
for that application.


> > > But component state is lost in the "refresh". Meaning 
> that for a SAX 
> > > transformer or *any other component with state* you have 
> screwed up 
> > > the processing. (So don't allow components with state, 
> then - well, 
> > > then they are all ThreadSafe and we do not need
> > > pools.)
> > 
> > See above.  The Cocoon pipeline component interfaces are really 
> > screwed up in this respect.  A component's state should be 
> sufficient 
> > per thread.
> 
> Thread can require several components of the same type to do 
> its work. How this will be handled?

Use the ***Manager approach above.  If you need a unique instance of
a component for each lookup, then there is probably something wrong
in your design.



> > Anything that is more granular than that needs a
> > different treatment.
> 
> What could it be?

A **Manager approach outlined above.


> > > The basis of GC is that you can unambiguously tell when 
> an object is 
> > > no longer used - when it can not possibly be used. The 
> speedups we 
> > > have in pooling is due to explicitly telling the 
> container that this 
> > > object can be reclaimed, thus keeping the object count low.
> > 
> > In Cocoon we have the advantage of knowing that.  A 
> pipeline component 
> > cannot possibly be used past the processing of a request.
> 
> Some transformers use instance of serializers to do its work. 
> It could be looked up on startup and returned on shutdown (to 
> speedup processing
> - right now manager.release() is quite expensive operation), 
> and will not depend on request/response cycles.

:) And now you are getting why we need to design our components
so that we do not need to release() them.  BTW, The Fortress
container has a much shorter release() cycle because it handles
the logic asyncronously.  It may take a little longer getting the
instance into the pool, but it doesn't affect the critical path.

However, if a Transformer directly uses a Serializer then something
is wrong.  That was never the intention of the Cocoon component
model.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Vadim Gritsenko [mailto:vadim.gritsenko@verizon.net] 
> 
> > From: Berin Loritsch [mailto:bloritsch@apache.org]
> 
> <snip-a-lot/>
> 
> ASSUMPTION:
> 
>   Poolable component is a component with high instantiation 
> cost and state thus it can not be used in several threads 
> simultaneously.
> 

Don't forget Per-Thread policy (not in ECM, but in new Fortress
package).  That instantiates one instance of a component per
thread, and you don't need pooling semantics to do it.

So that assumption is too broad.

Poolable components are for components that must be unique to
each lookup.  It is these types of components that should be
changed.  The Transformer is a perfect example of that.


> > However, the interfaces for the Cocoon pipeline components 
> are broken. 
> > A Generator should return an XMLSource, a Transformer 
> should return an 
> > interface that merges XMLSource and ContentHandler, and a
> Serializer
> > should return a ContentHandler.
> 
> Right now Transformers are poolable. They have a state and they are
> (supposedly) heavy to new().

Some of them are.  Their heaviness comes from the lifecycle they
must go through before they are ready to be used.  Some trivial
Transformers that do not need context information, or to lookup
other components, or to be configured are better off new()ing
every time.


> If you to change Transformer interface to return only 
> XMLSource/ContentHandler, all the logic and state Transformer 
> has moves into this XMLSource.

The state information moves into an artifact of the runtime
system.  This is as it should be.  We can query the component
for a unique instance of the XMLPipeline (merging of XMLSource
and ContentHander)--opening the door for other types of performance
enhancing opportunities.  Once the XSLT transformer has generated
the template, it can use a cached version of it--and the logic
makes sense.  Consider this use case:

--------Current State----------

generator.setup(....); // finds out the source info, etc...
transformer.setup(....); // finds out the source info, etc...
serializer.setup(....);

transformer.setContentHandler( serializer );
generator.setContentHandler( transformer );
generator.execute();

-------New Way-----------

XMLSource source = generator.getSource( type, .... ); // can cache at
this point
XMLPipeline pipe = transformer.getPipeline ( type, .... ); // can cache
at this point
ContentHandler sink = serializer.getSink( type, .... ); // can cache at
this point..if necessary

source.setContentHandler( pipe );
pipe.setConentHandler( sink );
source.execute();

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

It also helps in assembling the pipeline dynamically, with fewer
lookups.

The fact that we work with fairly generic types allows us the ability
to take advantage of generative programming such as using BCEL to
generate
a class that spits out SAX events (kind of like XSP but better)--and
have that done by the caching system.  The Generator component's
responsibility
then becomes how to manage these artifacts rather than how to actually
do the work.

The new way would probably add a GeneratorManager for this purpose.
However,
the artifact returned is preinitialized with everything it needs.  The
GeneratorManager, TransformerManager, and SerializerManager can all take
care
of usage semantics if it handles pooled items.

Otherwise stated, it would be *more* correct to return artifacts to a
specific
manager than it would be to return it to a lookup mechanism.  What we
want to
restore is the separation of concerns for the lookup mechanism.  The CM
was
only designed to be a lookup mechanism--not a container.

> 
> Thus, XMLSource becomes heavy and Transformer light. 
> Obviously, Transformer becomes ThreadSafe (which is good) and 
> XMLSource must be made Poolable (its heavy, it is stateful).


Not necessarily--there are other possibilities for optimization
at a systemic level that would not otherwise present itself.


> Instead of having one component we ended up with two. Please 
> tell me I see things wrongly.
> 
> <snip what="simple pipeline"/>

You end up with one management component, and artifacts it returns.
Those artifacts can be cached results, compiled XML streams, or
C2 Generators, etc.  We are no longer limited by our architecture.
We can have more intelligent operations on the pipeline components.



> > As the ContentHandler.endDocument() is called on each item, 
> they are 
> > automatically returned to their pools.
> 
> Two issues on this one:
> 
> 1. endDocument might be never be called. I can discard 
> component after evaluating its cache ID or cache validity.
> 
> 2. endDocument does not necessarily indicates that I'm done 
> with this component. Simple example: you are using serializer 
> to serialize xml fragment 100 times. It would be logical to 
> make a loop:
> 
> serialier = lookup();
> for(;;){
>   serializer.setDestination();
>   serializer.startDocument();
>   ...
>   serializer.endDocument();
> }
> 

Wrong application.  It is a Transformers job to modify the XML
so that you have an XML fragment repeating 100 times.  The
Serializer should only opperate on the XML given to it.

A serializer should _*never*_ modify the content of the XML.  It
can only modify the binary stream's representation of it.


> > As to timeouts, we can use one policy for the container type.  For 
> > example, Cocoon would benefit from a request based approach.
> 
> What if processing continues after sending response?
> I.e., after endDocument() on serializer, some work is done in 
> transformer? Like invoking other serializer?

Then you have broken Cocoon's design.  A Transformer does not invoke
serializer.  Ever.  It is the Sitemap's responsibility to manage all
pipelines--whether they have branched or not.  Once all processing for
a request is done--and the sitemap or at least the Cocoon container
knows this unequivicably--then it can reclaim the components.


> > Other
> > containers may have to use a timeout based approach.  Its up to the 
> > container.  Are timeouts sufficient?  No.  Does it add additional 
> > complexity for the container? Yes.  Does it help the developer? 
> > absolutely.
> 
> There are situations when transaction takes hours to process 
> (I do not mean DB transaction here). How this will happen?

Wow.  Hours?  Then you need to think of a different way of handling that
transaction.  That is a deeper design issue that needs serious thought
for that application.


> > > But component state is lost in the "refresh". Meaning 
> that for a SAX 
> > > transformer or *any other component with state* you have 
> screwed up 
> > > the processing. (So don't allow components with state, 
> then - well, 
> > > then they are all ThreadSafe and we do not need
> > > pools.)
> > 
> > See above.  The Cocoon pipeline component interfaces are really 
> > screwed up in this respect.  A component's state should be 
> sufficient 
> > per thread.
> 
> Thread can require several components of the same type to do 
> its work. How this will be handled?

Use the ***Manager approach above.  If you need a unique instance of
a component for each lookup, then there is probably something wrong
in your design.



> > Anything that is more granular than that needs a
> > different treatment.
> 
> What could it be?

A **Manager approach outlined above.


> > > The basis of GC is that you can unambiguously tell when 
> an object is 
> > > no longer used - when it can not possibly be used. The 
> speedups we 
> > > have in pooling is due to explicitly telling the 
> container that this 
> > > object can be reclaimed, thus keeping the object count low.
> > 
> > In Cocoon we have the advantage of knowing that.  A 
> pipeline component 
> > cannot possibly be used past the processing of a request.
> 
> Some transformers use instance of serializers to do its work. 
> It could be looked up on startup and returned on shutdown (to 
> speedup processing
> - right now manager.release() is quite expensive operation), 
> and will not depend on request/response cycles.

:) And now you are getting why we need to design our components
so that we do not need to release() them.  BTW, The Fortress
container has a much shorter release() cycle because it handles
the logic asyncronously.  It may take a little longer getting the
instance into the pool, but it doesn't affect the critical path.

However, if a Transformer directly uses a Serializer then something
is wrong.  That was never the intention of the Cocoon component
model.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Berin Loritsch [mailto:bloritsch@apache.org]

<snip-a-lot/>

ASSUMPTION:

  Poolable component is a component with high instantiation cost and
state thus it can not be used in several threads simultaneously.



> However, the interfaces for the Cocoon pipeline components are broken.
> A Generator should return an XMLSource, a Transformer should return
> an interface that merges XMLSource and ContentHandler, and a
Serializer
> should return a ContentHandler.

Right now Transformers are poolable. They have a state and they are
(supposedly) heavy to new().

If you to change Transformer interface to return only
XMLSource/ContentHandler, all the logic and state Transformer has moves
into this XMLSource.

Thus, XMLSource becomes heavy and Transformer light. Obviously,
Transformer becomes ThreadSafe (which is good) and XMLSource must be
made Poolable (its heavy, it is stateful).

Instead of having one component we ended up with two. Please tell me I
see things wrongly.

<snip what="simple pipeline"/>


> As the ContentHandler.endDocument() is called on each item, they are
> automatically returned to their pools.

Two issues on this one:

1. endDocument might be never be called. I can discard component after
evaluating its cache ID or cache validity.

2. endDocument does not necessarily indicates that I'm done with this
component. Simple example: you are using serializer to serialize xml
fragment 100 times. It would be logical to make a loop:

serialier = lookup();
for(;;){
  serializer.setDestination();
  serializer.startDocument();
  ...
  serializer.endDocument();
}

<snip/>


> As to timeouts, we can use one policy for the container type.  For
> example, Cocoon would benefit from a request based approach.

What if processing continues after sending response?
I.e., after endDocument() on serializer, some work is done in
transformer? Like invoking other serializer?


> Other
> containers may have to use a timeout based approach.  Its up to the
> container.  Are timeouts sufficient?  No.  Does it add additional
> complexity for the container? Yes.  Does it help the developer?
> absolutely.

There are situations when transaction takes hours to process (I do not
mean DB transaction here). How this will happen?

<snip/>


> > But component state is lost in the "refresh". Meaning that for
> > a SAX transformer or *any other component with state* you have
> > screwed up the processing. (So don't allow components with
> > state, then - well, then they are all ThreadSafe and we do not need
> > pools.)
> 
> See above.  The Cocoon pipeline component interfaces are really
> screwed up in this respect.  A component's state should be sufficient
> per thread. 

Thread can require several components of the same type to do its work.
How this will be handled?


> Anything that is more granular than that needs a
> different treatment.

What could it be?


> > The basis of GC is that you can unambiguously tell when an
> > object is no longer used - when it can not possibly be used.
> > The speedups we have in pooling is due to explicitly telling
> > the container that this object can be reclaimed, thus keeping
> > the object count low.
> 
> In Cocoon we have the advantage of knowing that.  A pipeline
> component cannot possibly be used past the processing of a request.

Some transformers use instance of serializers to do its work. It could
be looked up on startup and returned on shutdown (to speedup processing
- right now manager.release() is quite expensive operation), and will
not depend on request/response cycles.


Vadim

<snip/>


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Berin Loritsch [mailto:bloritsch@apache.org]

<snip-a-lot/>

ASSUMPTION:

  Poolable component is a component with high instantiation cost and
state thus it can not be used in several threads simultaneously.



> However, the interfaces for the Cocoon pipeline components are broken.
> A Generator should return an XMLSource, a Transformer should return
> an interface that merges XMLSource and ContentHandler, and a
Serializer
> should return a ContentHandler.

Right now Transformers are poolable. They have a state and they are
(supposedly) heavy to new().

If you to change Transformer interface to return only
XMLSource/ContentHandler, all the logic and state Transformer has moves
into this XMLSource.

Thus, XMLSource becomes heavy and Transformer light. Obviously,
Transformer becomes ThreadSafe (which is good) and XMLSource must be
made Poolable (its heavy, it is stateful).

Instead of having one component we ended up with two. Please tell me I
see things wrongly.

<snip what="simple pipeline"/>


> As the ContentHandler.endDocument() is called on each item, they are
> automatically returned to their pools.

Two issues on this one:

1. endDocument might be never be called. I can discard component after
evaluating its cache ID or cache validity.

2. endDocument does not necessarily indicates that I'm done with this
component. Simple example: you are using serializer to serialize xml
fragment 100 times. It would be logical to make a loop:

serialier = lookup();
for(;;){
  serializer.setDestination();
  serializer.startDocument();
  ...
  serializer.endDocument();
}

<snip/>


> As to timeouts, we can use one policy for the container type.  For
> example, Cocoon would benefit from a request based approach.

What if processing continues after sending response?
I.e., after endDocument() on serializer, some work is done in
transformer? Like invoking other serializer?


> Other
> containers may have to use a timeout based approach.  Its up to the
> container.  Are timeouts sufficient?  No.  Does it add additional
> complexity for the container? Yes.  Does it help the developer?
> absolutely.

There are situations when transaction takes hours to process (I do not
mean DB transaction here). How this will happen?

<snip/>


> > But component state is lost in the "refresh". Meaning that for
> > a SAX transformer or *any other component with state* you have
> > screwed up the processing. (So don't allow components with
> > state, then - well, then they are all ThreadSafe and we do not need
> > pools.)
> 
> See above.  The Cocoon pipeline component interfaces are really
> screwed up in this respect.  A component's state should be sufficient
> per thread. 

Thread can require several components of the same type to do its work.
How this will be handled?


> Anything that is more granular than that needs a
> different treatment.

What could it be?


> > The basis of GC is that you can unambiguously tell when an
> > object is no longer used - when it can not possibly be used.
> > The speedups we have in pooling is due to explicitly telling
> > the container that this object can be reclaimed, thus keeping
> > the object count low.
> 
> In Cocoon we have the advantage of knowing that.  A pipeline
> component cannot possibly be used past the processing of a request.

Some transformers use instance of serializers to do its work. It could
be looked up on startup and returned on shutdown (to speedup processing
- right now manager.release() is quite expensive operation), and will
not depend on request/response cycles.


Vadim

<snip/>


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com] 
> 
> > From: Berin Loritsch [mailto:bloritsch@apache.org]
> 
> > > Assume you have a CM that automatically reclaims all components 
> > > after each request. That is, for Cocoon, when the request 
> comes in, 
> > > the CM starts keeping track of what components have been 
> taken out, 
> > > and when the request has been processed, they are release()'d (or 
> > > equivalent method).
> > > 
> > > Now introduce pooled components.
> > > 
> > >     If more than pool-max components are looked-up during 
> > >     the request you are not performing well, as you empty
> > >     the pool.
> > 
> > I thought I already did introduce pooled components.  It's
> > really simple.  The GC process for components releases 
> > them--just like we currently do. The GC process is done 
> > after the Response is committed.
> 
> The scenario was when more than pool-max lookups had been
> done before the GC kicks in. Suppose you have a pool-max of 3:
> 
>    public void handleRequest () {
>       someMethod ();
>       someMethod ();      
>       someMethod ();
>       someMethod ();
>    }

And this is different from the current state of affairs, how?
If a request requires 5 transformer instances, and you have your
pool max set to 3, you will still experience slow down.  This
is no different than automatically releasing a component when
the request is handled.


>    public void someMethod () {
>       manager.lookup (ExpensiveButPooledComponent.ROLE);
>       ...
>    }
> 
> With an explicit release() this could be made not to drain 
> the pool. With GC you can not, unless you set the timeout 
> ridiculously low.

With an explicit release() you are in the same boat as the GC
method.  For Cocoon we have a really simple lifelength for
requested components: the length of a request.  It's not that
hard to implement or to comprehend.  It is also pretty easy
to manage the instances available.

Many of the components that are currently pooled can be made
into a PerThread policy.  All we need is a ThreadLocal variable
to create the instance of the object.  This accounts for a
large majority.  Unfortunately, the core components in Cocoon
have an interface that is not friendly, and we need a unique
instance for every request.  AKA pooling.

I am also advocating that the current pipeline component interfaces
be changed.  The Generator, Transformer, and Serializer implement
SAX methods--which is mixing concerns.  They should return one.

Now, we can set it up so that we can have a new version of
the interface without breaking backwards compatibility with
current components--but that is a subject for another thread.

There is something inherently wrong when the only option available
to you is to pool the components or create them new every time.
The interface is wrong.  It adds overhead and long and drawn out
witch hunts finding where the component references are leaking.

If we can design the components so that they can either be shared
among all threads (optimal), or at the very least ensure that one
instance per thread is sufficient then we have something where
the framework is no longer the issue and we no longer need the
release() mechanism.

The issues come with the forcing of Poolable.  That decision should
be something that the container can decide to implement if it wants
to--possibly to save instances so that the number of instances of
a component are fewer than the number of threads.

However, the interfaces for the Cocoon pipeline components are broken.
A Generator should return an XMLSource, a Transformer should return
an interface that merges XMLSource and ContentHandler, and a Serializer
should return a ContentHandler.

That way we can have something as simple as


XMLSource source = generator.getXMLSource("file", uri);
XMLSource trans = source;
Iterator xformers = transformers.iterator();

while ( xformers.hasNext() )
{
    Struct entry = (XMLSource)xformers.next();
    XMLSource newTrans = transformers.getPipeline(newTrans.type,
newTrans.uri)
    trans.setContentHandler(newTrans);
    trans = newTrans;
}

trans.setContentHandler( serializer.getHandler("svg2png") );

source.execute();

As the ContentHandler.endDocument() is called on each item, they are
automatically returned to their pools.  Its not bad.  Not to mention,
the current style generators, transformers, and serializers whould
be able to be used as the return values--so that everyone's hard work
is not wasted.


> > The GC routine for the container collects any components that
> > need to be reclaimed into the pool.  As a result we will have 
> > fewer dangling components than is currently possible.  Right 
> > now, we have the equivalent of C++ memory allocation.  The 
> > onus is on the developer to get it right.  The GC brings the 
> > component into the Java age where GC is the norm.  You don't 
> > have to worry about deleting everything you new in Java, the 
> > user doesn't have to worry about releasing everything you lookup.
> 
> Well that's fine in theory, but in practice you will end up tweaking 
> and tweaking your GC timeouts and pool sizes, getting bizarre 
> errors along the way.

You already have to skrew with pool sizes.  The GC element is not
going to make things less predictable on that front.  In fact, it
is a good possibility to make it *more* predictable.

As to timeouts, we can use one policy for the container type.  For
example, Cocoon would benefit from a request based approach.  Other
containers may have to use a timeout based approach.  Its up to the
container.  Are timeouts sufficient?  No.  Does it add additional
complexity for the container? Yes.  Does it help the developer?
absolutely.


> > Example:
> > 
> > Proxy that releases the component instance after a timeout of
> > 100 ms will wait as a container of nothing until it is either 
> > GC'd by the JVM or until an interface method has been called. 
> > In that case, the call blocks until a new Component instance 
> > is pulled from the pool.  The method is then called.
> 
> But component state is lost in the "refresh". Meaning that for 
> a SAX transformer or *any other component with state* you have 
> screwed up the processing. (So don't allow components with 
> state, then - well, then they are all ThreadSafe and we do not need 
> pools.)

See above.  The Cocoon pipeline component interfaces are really
screwed up in this respect.  A component's state should be sufficient
per thread.  Anything that is more granular than that needs a
different treatment.


> The basis of GC is that you can unambiguously tell when an 
> object is no longer used - when it can not possibly be used. 
> The speedups we have in pooling is due to explicitly telling 
> the container that this object can be reclaimed, thus keeping 
> the object count low.

In Cocoon we have the advantage of knowing that.  A pipeline
component cannot possibly be used past the processing of a request.
It makes for a really simple GC mechanism.


> > I do not want any more work on the client.  Let the container
> > be smart and the client be dumb.
> 
> Agreed! But what you propose is simply too complex to ever 
> work in practice. There are just too many restrictions on how 
> a component may behave, too many parameters for the GC 
> policy. Too much that can go wrong.

I am finding more and more what people are calling components are
nothing more than Objects that observe the Bridge pattern.  They
implement an interface, introduce a few lifecycle methods, etc.
If they are object then they should be treated as such.  If a
pooled object requires an explicit return to a pool, than that
decision should be made in the GeneratorManager, or the
TransformerManager, etc.  Not in the core lookup mechanism.


> Add in different GC policies for different containers and
> you end up with making the whole thing more complex instead of 
> less.
> 
> Summary: GC of components...
> 
>      ...means that components may not have state and be pooled.

It means that the state has to be at least consistent within a thread.
Of course, the proxy can maintain the state as well--but that is more
complexity as well....

>      ...means that you always risk draining the pool.

That is the notion that I am trying to dispell.  It means that there
is fewer instances of memory leaks in Cocoon because what one developer
forgot to release is not going to hurt everyone else.

>      ...means a load of GC policy parameters for the client.

? I don't get this at all.

GC policy is a function of the container--the client has no say in
its use.  The JVM does not have programmatic hooks to allow you to
modify at runtime what GC policy it has.  The fact that it has a
System.gc() method is too much IMO to give to a client.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com] 
> 
> > From: Berin Loritsch [mailto:bloritsch@apache.org]
> 
> > > Assume you have a CM that automatically reclaims all components 
> > > after each request. That is, for Cocoon, when the request 
> comes in, 
> > > the CM starts keeping track of what components have been 
> taken out, 
> > > and when the request has been processed, they are release()'d (or 
> > > equivalent method).
> > > 
> > > Now introduce pooled components.
> > > 
> > >     If more than pool-max components are looked-up during 
> > >     the request you are not performing well, as you empty
> > >     the pool.
> > 
> > I thought I already did introduce pooled components.  It's
> > really simple.  The GC process for components releases 
> > them--just like we currently do. The GC process is done 
> > after the Response is committed.
> 
> The scenario was when more than pool-max lookups had been
> done before the GC kicks in. Suppose you have a pool-max of 3:
> 
>    public void handleRequest () {
>       someMethod ();
>       someMethod ();      
>       someMethod ();
>       someMethod ();
>    }

And this is different from the current state of affairs, how?
If a request requires 5 transformer instances, and you have your
pool max set to 3, you will still experience slow down.  This
is no different than automatically releasing a component when
the request is handled.


>    public void someMethod () {
>       manager.lookup (ExpensiveButPooledComponent.ROLE);
>       ...
>    }
> 
> With an explicit release() this could be made not to drain 
> the pool. With GC you can not, unless you set the timeout 
> ridiculously low.

With an explicit release() you are in the same boat as the GC
method.  For Cocoon we have a really simple lifelength for
requested components: the length of a request.  It's not that
hard to implement or to comprehend.  It is also pretty easy
to manage the instances available.

Many of the components that are currently pooled can be made
into a PerThread policy.  All we need is a ThreadLocal variable
to create the instance of the object.  This accounts for a
large majority.  Unfortunately, the core components in Cocoon
have an interface that is not friendly, and we need a unique
instance for every request.  AKA pooling.

I am also advocating that the current pipeline component interfaces
be changed.  The Generator, Transformer, and Serializer implement
SAX methods--which is mixing concerns.  They should return one.

Now, we can set it up so that we can have a new version of
the interface without breaking backwards compatibility with
current components--but that is a subject for another thread.

There is something inherently wrong when the only option available
to you is to pool the components or create them new every time.
The interface is wrong.  It adds overhead and long and drawn out
witch hunts finding where the component references are leaking.

If we can design the components so that they can either be shared
among all threads (optimal), or at the very least ensure that one
instance per thread is sufficient then we have something where
the framework is no longer the issue and we no longer need the
release() mechanism.

The issues come with the forcing of Poolable.  That decision should
be something that the container can decide to implement if it wants
to--possibly to save instances so that the number of instances of
a component are fewer than the number of threads.

However, the interfaces for the Cocoon pipeline components are broken.
A Generator should return an XMLSource, a Transformer should return
an interface that merges XMLSource and ContentHandler, and a Serializer
should return a ContentHandler.

That way we can have something as simple as


XMLSource source = generator.getXMLSource("file", uri);
XMLSource trans = source;
Iterator xformers = transformers.iterator();

while ( xformers.hasNext() )
{
    Struct entry = (XMLSource)xformers.next();
    XMLSource newTrans = transformers.getPipeline(newTrans.type,
newTrans.uri)
    trans.setContentHandler(newTrans);
    trans = newTrans;
}

trans.setContentHandler( serializer.getHandler("svg2png") );

source.execute();

As the ContentHandler.endDocument() is called on each item, they are
automatically returned to their pools.  Its not bad.  Not to mention,
the current style generators, transformers, and serializers whould
be able to be used as the return values--so that everyone's hard work
is not wasted.


> > The GC routine for the container collects any components that
> > need to be reclaimed into the pool.  As a result we will have 
> > fewer dangling components than is currently possible.  Right 
> > now, we have the equivalent of C++ memory allocation.  The 
> > onus is on the developer to get it right.  The GC brings the 
> > component into the Java age where GC is the norm.  You don't 
> > have to worry about deleting everything you new in Java, the 
> > user doesn't have to worry about releasing everything you lookup.
> 
> Well that's fine in theory, but in practice you will end up tweaking 
> and tweaking your GC timeouts and pool sizes, getting bizarre 
> errors along the way.

You already have to skrew with pool sizes.  The GC element is not
going to make things less predictable on that front.  In fact, it
is a good possibility to make it *more* predictable.

As to timeouts, we can use one policy for the container type.  For
example, Cocoon would benefit from a request based approach.  Other
containers may have to use a timeout based approach.  Its up to the
container.  Are timeouts sufficient?  No.  Does it add additional
complexity for the container? Yes.  Does it help the developer?
absolutely.


> > Example:
> > 
> > Proxy that releases the component instance after a timeout of
> > 100 ms will wait as a container of nothing until it is either 
> > GC'd by the JVM or until an interface method has been called. 
> > In that case, the call blocks until a new Component instance 
> > is pulled from the pool.  The method is then called.
> 
> But component state is lost in the "refresh". Meaning that for 
> a SAX transformer or *any other component with state* you have 
> screwed up the processing. (So don't allow components with 
> state, then - well, then they are all ThreadSafe and we do not need 
> pools.)

See above.  The Cocoon pipeline component interfaces are really
screwed up in this respect.  A component's state should be sufficient
per thread.  Anything that is more granular than that needs a
different treatment.


> The basis of GC is that you can unambiguously tell when an 
> object is no longer used - when it can not possibly be used. 
> The speedups we have in pooling is due to explicitly telling 
> the container that this object can be reclaimed, thus keeping 
> the object count low.

In Cocoon we have the advantage of knowing that.  A pipeline
component cannot possibly be used past the processing of a request.
It makes for a really simple GC mechanism.


> > I do not want any more work on the client.  Let the container
> > be smart and the client be dumb.
> 
> Agreed! But what you propose is simply too complex to ever 
> work in practice. There are just too many restrictions on how 
> a component may behave, too many parameters for the GC 
> policy. Too much that can go wrong.

I am finding more and more what people are calling components are
nothing more than Objects that observe the Bridge pattern.  They
implement an interface, introduce a few lifecycle methods, etc.
If they are object then they should be treated as such.  If a
pooled object requires an explicit return to a pool, than that
decision should be made in the GeneratorManager, or the
TransformerManager, etc.  Not in the core lookup mechanism.


> Add in different GC policies for different containers and
> you end up with making the whole thing more complex instead of 
> less.
> 
> Summary: GC of components...
> 
>      ...means that components may not have state and be pooled.

It means that the state has to be at least consistent within a thread.
Of course, the proxy can maintain the state as well--but that is more
complexity as well....

>      ...means that you always risk draining the pool.

That is the notion that I am trying to dispell.  It means that there
is fewer instances of memory leaks in Cocoon because what one developer
forgot to release is not going to hurt everyone else.

>      ...means a load of GC policy parameters for the client.

? I don't get this at all.

GC policy is a function of the container--the client has no say in
its use.  The JVM does not have programmatic hooks to allow you to
modify at runtime what GC policy it has.  The fact that it has a
System.gc() method is too much IMO to give to a client.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Berin Loritsch [mailto:bloritsch@apache.org] 
>
> > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > 
> > Berin,
> > 
> > I am 75% for your new CM interface. The problem is point 4.
> 
> Am I not a prophet?

:) 

> > Assume you have a CM that automatically reclaims all
> > components after each request. That is, for Cocoon, when the 
> > request comes in, the CM starts keeping track of what 
> > components have been taken out, and when the request has been 
> > processed, they are release()'d (or equivalent method).
> > 
> > Now introduce pooled components.
> > 
> >     If more than pool-max components are looked-up during 
> >     the request you are not performing well, as you empty
> >     the pool.
> 
> I thought I already did introduce pooled components.  It's 
> really simple.  The GC process for components releases 
> them--just like we currently do. The GC process is done 
> after the Response is committed.

The scenario was when more than pool-max lookups had been
done before the GC kicks in. Suppose you have a pool-max of 3:

   public void handleRequest () {
      someMethod ();
      someMethod ();      
      someMethod ();
      someMethod ();
   }

   public void someMethod () {
      manager.lookup (ExpensiveButPooledComponent.ROLE);
      ...
   }

With an explicit release() this could be made not to drain the pool.
With GC you can not, unless you set the timeout ridiculously low.

> The GC routine for the container collects any components that 
> need to be reclaimed into the pool.  As a result we will have 
> fewer dangling components than is currently possible.  Right 
> now, we have the equivalent of C++ memory allocation.  The 
> onus is on the developer to get it right.  The GC brings the 
> component into the Java age where GC is the norm.  You don't 
> have to worry about deleting everything you new in Java, the 
> user doesn't have to worry about releasing everything you lookup.

Well that's fine in theory, but in practice you will end up tweaking 
and tweaking your GC timeouts and pool sizes, getting bizarre
errors along the way.

> Example:
> 
> Proxy that releases the component instance after a timeout of 
> 100 ms will wait as a container of nothing until it is either 
> GC'd by the JVM or until an interface method has been called. 
> In that case, the call blocks until a new Component instance 
> is pulled from the pool.  The method is then called.

But component state is lost in the "refresh". Meaning that for 
a SAX transformer or *any other component with state* you have 
screwed up the processing. (So don't allow components with state,
then - well, then they are all ThreadSafe and we do not need 
pools.)

The basis of GC is that you can unambiguously tell when an 
object is no longer used - when it can not possibly be used.
The speedups we have in pooling is due to explicitly telling
the container that this object can be reclaimed, thus keeping
the object count low.

> I do not want any more work on the client.  Let the container 
> be smart and the client be dumb.

Agreed! But what you propose is simply too complex to ever work
in practice. There are just too many restrictions on how a
component may behave, too many parameters for the GC policy.
Too much that can go wrong.

Add in different GC policies for different containers and
you end up with making the whole thing more complex instead of 
less.

Summary: GC of components...

     ...means that components may not have state and be pooled.
     ...means that you always risk draining the pool.
     ...means a load of GC policy parameters for the client.

/LS


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Berin Loritsch [mailto:bloritsch@apache.org] 
>
> > From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> > 
> > Berin,
> > 
> > I am 75% for your new CM interface. The problem is point 4.
> 
> Am I not a prophet?

:) 

> > Assume you have a CM that automatically reclaims all
> > components after each request. That is, for Cocoon, when the 
> > request comes in, the CM starts keeping track of what 
> > components have been taken out, and when the request has been 
> > processed, they are release()'d (or equivalent method).
> > 
> > Now introduce pooled components.
> > 
> >     If more than pool-max components are looked-up during 
> >     the request you are not performing well, as you empty
> >     the pool.
> 
> I thought I already did introduce pooled components.  It's 
> really simple.  The GC process for components releases 
> them--just like we currently do. The GC process is done 
> after the Response is committed.

The scenario was when more than pool-max lookups had been
done before the GC kicks in. Suppose you have a pool-max of 3:

   public void handleRequest () {
      someMethod ();
      someMethod ();      
      someMethod ();
      someMethod ();
   }

   public void someMethod () {
      manager.lookup (ExpensiveButPooledComponent.ROLE);
      ...
   }

With an explicit release() this could be made not to drain the pool.
With GC you can not, unless you set the timeout ridiculously low.

> The GC routine for the container collects any components that 
> need to be reclaimed into the pool.  As a result we will have 
> fewer dangling components than is currently possible.  Right 
> now, we have the equivalent of C++ memory allocation.  The 
> onus is on the developer to get it right.  The GC brings the 
> component into the Java age where GC is the norm.  You don't 
> have to worry about deleting everything you new in Java, the 
> user doesn't have to worry about releasing everything you lookup.

Well that's fine in theory, but in practice you will end up tweaking 
and tweaking your GC timeouts and pool sizes, getting bizarre
errors along the way.

> Example:
> 
> Proxy that releases the component instance after a timeout of 
> 100 ms will wait as a container of nothing until it is either 
> GC'd by the JVM or until an interface method has been called. 
> In that case, the call blocks until a new Component instance 
> is pulled from the pool.  The method is then called.

But component state is lost in the "refresh". Meaning that for 
a SAX transformer or *any other component with state* you have 
screwed up the processing. (So don't allow components with state,
then - well, then they are all ThreadSafe and we do not need 
pools.)

The basis of GC is that you can unambiguously tell when an 
object is no longer used - when it can not possibly be used.
The speedups we have in pooling is due to explicitly telling
the container that this object can be reclaimed, thus keeping
the object count low.

> I do not want any more work on the client.  Let the container 
> be smart and the client be dumb.

Agreed! But what you propose is simply too complex to ever work
in practice. There are just too many restrictions on how a
component may behave, too many parameters for the GC policy.
Too much that can go wrong.

Add in different GC policies for different containers and
you end up with making the whole thing more complex instead of 
less.

Summary: GC of components...

     ...means that components may not have state and be pooled.
     ...means that you always risk draining the pool.
     ...means a load of GC policy parameters for the client.

/LS


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com] 
> 
> Berin,
> 
> I am 75% for your new CM interface. The problem is point 4.

Am I not a prophet?


> Assume you have a CM that automatically reclaims all 
> components after each request. That is, for Cocoon, when the 
> request comes in, the CM starts keeping track of what 
> components have been taken out, and when the request has been 
> processed, they are release()'d (or equivalent method).
> 
> Now introduce pooled components.
> 
>     If more than pool-max components are looked-up during 
>     the request you are not performing well, as you empty
>     the pool.

I thought I already did introduce pooled components.  It's
really simple.  The GC process for components releases them--just
like we currently do.  The GC process is done after the Response is
committed.  The difference is in *who* releases the component.
The onus is on the container--which already automatically tracks
each component anyway.

What is happening is that we don't have to rely on the developer
to remember to release the component in the proper location.  That
ends the problems with memory leaks because some error condition
forces the function to exit before the component is released.


> What I need to be convinced that release() isn't needed is:
> 
>  + a description of how does it work with pooled components

Did you not read the entire mail?

The GC routine for the container collects any components that need
to be reclaimed into the pool.  As a result we will have fewer
dangling components than is currently possible.  Right now, we have
the equivalent of C++ memory allocation.  The onus is on the developer
to get it right.  The GC brings the component into the Java age where
GC is the norm.  You don't have to worry about deleting everything
you new in Java, the user doesn't have to worry about releasing
everything you lookup.

> 
>  + a guarantee that the client will *never* have to care about 
>    whether a component is pooled or not. And I do not mean
>    a mandatory 
> 
>       if (component instanceof Poolable) 
>           manager.release (component);

It happens in the container.  The policy can be a timeout, or it
can be request based.  Whatever.  The container tracks what components
were looked up (as it can do), and when the GC policy indicates it
is time to collect instances--the container does the hard work.
It isn't as hard as it seems.


> > From: Berin Loritsch [mailto:bloritsch@apache.org]
> > 
> > In order to make it easier for the component developers, we
> > need to have a dynamic proxy generator (that would also help 
> > with DataSourceComponet too...). It would wrap the interface 
> > to enable garbage collection of components. All a client is 
> > responsible for is to request the component.
> 
> The problem with this being that you have to care about 
> whether a component is pooled or not to get maximum performance.

No, that is the container's responsibility.


> Assuming a component that is expensive to instantiate but 
> often used and that does not have an unambiguously defined 
> end-of-duty event like the SAXTransformer's endDocument you 
> are left with two choices:
> 
>  1) Add a "return-to-pool" method that the client must call.

If your component interface has a method that is called when you
are done (ala JDBC Connection.close()) then that is one natural
clue to the container.  The GC mechanism is still the best.


>  2) Add a timeout, which must be set low for the instance to
>     have time to return to the container in time for the next use.
> 
> In case 1, this method is equivalent to release(), and you have just 
> traded one mandatory method call for another. Case 2 is just 
> not very good - set the timeout too low and you will get 
> problems if the component is still used after it has timed out.

Like I said it does require a change in how you think about
components and their interfaces.  I am advocating a GC mechanism
which is orthagonal to either 1 or 2.  For Cocoon the GC policy
would be after the Response is committed.  For something else,
a timeout policy might be worthwhile.

For yet another solution, the Container can essentially combine
timeout and guranteeing a reference is good.

Example:

Proxy that releases the component instance after a timeout of
100 ms will wait as a container of nothing until it is either
GC'd by the JVM or until an interface method has been called.
In that case, the call blocks until a new Component instance
is pulled from the pool.  The method is then called.

> 
> More about (1) - if you want to create
> 
>     public interface Releasable {
>         public void release ();
>     }

No!  I do not want that.  If a component belongs to a pool, the
container will simply return it.  The proxy is generated dynamically,
and the container takes care of the GC process.


> and let the dynamic proxy implement this - that is, you do
> a lookup, and you get something back that implements 
> Releasable - then the client must cast the reference it 
> obtained to Releaseable in order to release it (which it 
> must, as it does not know whether the component is pooled or 
> not). So every component interface that does not have a 
> close() method or similar should extend Releasable 
> to avoid a cast. (And since the component can't really 
> implement the method, it should leave it empty.)

I do not want any more work on the client.  Let the container
be smart and the client be dumb.


> And then we're back where we started... With empty release() 
> methods not just in the CM, but all over the place.

No, no, no, no.

You aren't getting it.

The container tracks the instances that it needs to track (i.e. the
pooled instances), and GCs them automatically.  Nothing needs or
should be done by the client.   Period.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Berin Loritsch <bl...@apache.org>.
> From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com] 
> 
> Berin,
> 
> I am 75% for your new CM interface. The problem is point 4.

Am I not a prophet?


> Assume you have a CM that automatically reclaims all 
> components after each request. That is, for Cocoon, when the 
> request comes in, the CM starts keeping track of what 
> components have been taken out, and when the request has been 
> processed, they are release()'d (or equivalent method).
> 
> Now introduce pooled components.
> 
>     If more than pool-max components are looked-up during 
>     the request you are not performing well, as you empty
>     the pool.

I thought I already did introduce pooled components.  It's
really simple.  The GC process for components releases them--just
like we currently do.  The GC process is done after the Response is
committed.  The difference is in *who* releases the component.
The onus is on the container--which already automatically tracks
each component anyway.

What is happening is that we don't have to rely on the developer
to remember to release the component in the proper location.  That
ends the problems with memory leaks because some error condition
forces the function to exit before the component is released.


> What I need to be convinced that release() isn't needed is:
> 
>  + a description of how does it work with pooled components

Did you not read the entire mail?

The GC routine for the container collects any components that need
to be reclaimed into the pool.  As a result we will have fewer
dangling components than is currently possible.  Right now, we have
the equivalent of C++ memory allocation.  The onus is on the developer
to get it right.  The GC brings the component into the Java age where
GC is the norm.  You don't have to worry about deleting everything
you new in Java, the user doesn't have to worry about releasing
everything you lookup.

> 
>  + a guarantee that the client will *never* have to care about 
>    whether a component is pooled or not. And I do not mean
>    a mandatory 
> 
>       if (component instanceof Poolable) 
>           manager.release (component);

It happens in the container.  The policy can be a timeout, or it
can be request based.  Whatever.  The container tracks what components
were looked up (as it can do), and when the GC policy indicates it
is time to collect instances--the container does the hard work.
It isn't as hard as it seems.


> > From: Berin Loritsch [mailto:bloritsch@apache.org]
> > 
> > In order to make it easier for the component developers, we
> > need to have a dynamic proxy generator (that would also help 
> > with DataSourceComponet too...). It would wrap the interface 
> > to enable garbage collection of components. All a client is 
> > responsible for is to request the component.
> 
> The problem with this being that you have to care about 
> whether a component is pooled or not to get maximum performance.

No, that is the container's responsibility.


> Assuming a component that is expensive to instantiate but 
> often used and that does not have an unambiguously defined 
> end-of-duty event like the SAXTransformer's endDocument you 
> are left with two choices:
> 
>  1) Add a "return-to-pool" method that the client must call.

If your component interface has a method that is called when you
are done (ala JDBC Connection.close()) then that is one natural
clue to the container.  The GC mechanism is still the best.


>  2) Add a timeout, which must be set low for the instance to
>     have time to return to the container in time for the next use.
> 
> In case 1, this method is equivalent to release(), and you have just 
> traded one mandatory method call for another. Case 2 is just 
> not very good - set the timeout too low and you will get 
> problems if the component is still used after it has timed out.

Like I said it does require a change in how you think about
components and their interfaces.  I am advocating a GC mechanism
which is orthagonal to either 1 or 2.  For Cocoon the GC policy
would be after the Response is committed.  For something else,
a timeout policy might be worthwhile.

For yet another solution, the Container can essentially combine
timeout and guranteeing a reference is good.

Example:

Proxy that releases the component instance after a timeout of
100 ms will wait as a container of nothing until it is either
GC'd by the JVM or until an interface method has been called.
In that case, the call blocks until a new Component instance
is pulled from the pool.  The method is then called.

> 
> More about (1) - if you want to create
> 
>     public interface Releasable {
>         public void release ();
>     }

No!  I do not want that.  If a component belongs to a pool, the
container will simply return it.  The proxy is generated dynamically,
and the container takes care of the GC process.


> and let the dynamic proxy implement this - that is, you do
> a lookup, and you get something back that implements 
> Releasable - then the client must cast the reference it 
> obtained to Releaseable in order to release it (which it 
> must, as it does not know whether the component is pooled or 
> not). So every component interface that does not have a 
> close() method or similar should extend Releasable 
> to avoid a cast. (And since the component can't really 
> implement the method, it should leave it empty.)

I do not want any more work on the client.  Let the container
be smart and the client be dumb.


> And then we're back where we started... With empty release() 
> methods not just in the CM, but all over the place.

No, no, no, no.

You aren't getting it.

The container tracks the instances that it needs to track (i.e. the
pooled instances), and GCs them automatically.  Nothing needs or
should be done by the client.   Period.


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


RE: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Leo Sutic <le...@inspireinfrastructure.com>.
Berin,

I am 75% for your new CM interface. The problem is point 4.

Assume you have a CM that automatically reclaims all components
after each request. That is, for Cocoon, when the request comes in,
the CM starts keeping track of what components have been taken out,
and when the request has been processed, they are release()'d (or
equivalent method).

Now introduce pooled components.

    If more than pool-max components are looked-up during 
    the request you are not performing well, as you empty
    the pool.

What I need to be convinced that release() isn't needed is:

 + a description of how does it work with pooled components

 + a guarantee that the client will *never* have to care about 
   whether a component is pooled or not. And I do not mean
   a mandatory 

      if (component instanceof Poolable) 
          manager.release (component);

> From: Berin Loritsch [mailto:bloritsch@apache.org] 
> 
> In order to make it easier for the component developers, we 
> need to have a dynamic proxy generator (that would also help 
> with DataSourceComponet too...). It would wrap the interface 
> to enable garbage collection of components. All a client is 
> responsible for is to request the component.

The problem with this being that you have to care about whether
a component is pooled or not to get maximum performance.

Assuming a component that is expensive to instantiate but often used
and that does not have an unambiguously defined end-of-duty event
like the SAXTransformer's endDocument you are left with two choices:

 1) Add a "return-to-pool" method that the client must call.

 2) Add a timeout, which must be set low for the instance to
    have time to return to the container in time for the next use.

In case 1, this method is equivalent to release(), and you have just 
traded one mandatory method call for another. Case 2 is just
not very good - set the timeout too low and you will get problems
if the component is still used after it has timed out.

More about (1) - if you want to create

    public interface Releasable {
        public void release ();
    }

and let the dynamic proxy implement this - that is, you do
a lookup, and you get something back that implements Releasable -
then the client must cast the reference it obtained to Releaseable
in order to release it (which it must, as it does not know whether
the component is pooled or not). So every component interface
that does not have a close() method or similar should extend Releasable 
to avoid a cast. (And since the component can't really implement
the method, it should leave it empty.)

And then we're back where we started... With empty release() methods
not just in the CM, but all over the place.

/LS


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


Re: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Robert Mouat <ro...@mouat.net>.
<delurk/>

On Thu, 6 Jun 2002, Berin Loritsch wrote:

<snip/>

> interface ComponentManager
> {
>     Object lookup(String role);
>     Object lookup(String role, Object hint);
>     boolean exists(String role);
>     boolean exists(String role, Object hint);
> }
> 
> If you notice, there are four distinct differences from the current
> ComponentManger:

<snip/>

> 4) We remove the release() method altogether.

With a combination of dynamic proxies and the Object.finalize() method
it should be possible to use the VM's garbage collector to release a
component.  This would allow the removal of the release() method, while
still guaranting that the component wasn't released until after the client
had finished using it.

how this would work:

- cm.lookup() returns a dynamic proxy implementing the interfaces of
the desired component.  This proxy will pass all interface calls onto
the real component.

- neither the container nor the component manager keep a reference to
the proxy (they are allowed a weak reference -- but we want the VM's
GC to tell us when the client nolonger holds a reference to it.

- the client uses the component (transparently via the proxy).

- when the client loses all references to the proxy the GC will call
the finalize() method on the proxy.  This method will do what the
cm.release() method currently does.

[note: it is the proxy that gets garbage collected, not the component]


how the code might look:

  class ReleasingProxy implements java.lang.reflect.InvocationHandler
  {

    private Object component;

    public ReleasingProxy( Object o )
    {
      component = o;
    }

    public Object invoke( Object proxy, Method method, Object[] args ) 
      throws Throwable
    {
      try
      {
        return method.invoke( component, args );
      }
      catch ( InvocationTargetException e )
      {
        throw e.getTargetException();
      }
    }  

    protected void finalize()
    {
      // code from cm.release() goes here.
    }

  }


in the lookup code 'return component;' can be replaced with:

  // may want to filter out the lifecycle interfaces...
  // they don't hurt, but it might be nice if they weren't
  // exposed to the client
  Class[] interfaces = component.getClass().getInterfaces();

  return java.lang.reflect.Proxy.newProxyInstance(
      classLoader,
      interfaces,
      new ReleasingProxy( component )
    );

[note: the ReleasingProxy will probably also need a reference to the
Container for doing the release]

Advantages:

- everything happens transparently to the client and component.

- the release code is only called after the client has lost all
references to the proxy (this actually makes it safer than using
cm.release())

Disadvantages:

- the release code is only called after the client has lost all
references to the proxy.

- relies on the VM's GC to return the component to the pool, and it is
unclear how long this will take.  [I don't know much about GC
implementations, but theoretically if there are no circular references
the reference count could become 0 and the VM could remove the object
immediately]

- requires JDK 1.3+

Robert.



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


Re: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Robert Mouat <ro...@mouat.net>.
<delurk/>
 
On Thu, 6 Jun 2002, Berin Loritsch wrote:
 
<snip/>
 
> interface ComponentManager
> {
>     Object lookup(String role);
>     Object lookup(String role, Object hint);
>     boolean exists(String role);
>     boolean exists(String role, Object hint);
> }
>
> If you notice, there are four distinct differences from the current
> ComponentManger:
 
<snip/>
 
> 4) We remove the release() method altogether.
 
With a combination of dynamic proxies and the Object.finalize() method
it should be possible to use the VM's garbage collector to release a
component.  This would be transparent to both the client and the
component.
 
how this could work:
 
- cm.lookup() returns a dynamix proxy implementing the interfaces of
the desired component.  This proxy will pass all interface calls onto
the real component.
 
- neither the container nor the component manager keep a reference to
the proxy (they are allowed a weak reference -- but we want the VM's
GC to tell us when the client nolonger holds a reference to it.
 
- the client uses the component (transparently via the proxy).
 
- when the client loses all references to the proxy the GC will call
the finalize() mothod on the proxy.  This method will do what the
cm.release() method currently does.

[note: it is the proxy that gets garbage collected, not the component]
 
 
how the code might look:
 
class ReleasingProxy implements java.lang.reflect.InvocationHandler
{
 
  private Object component;
 
  public ReleasingProxy( Object o )
  {
    component = o;
  }
 
  public Object invoke( Object proxy, Method method, Object[] args )
    throws Throwable
  {
    try
    {
      return method.invoke( component, args );
    }
    catch ( InvocationTargetException e )
    {
      throw e.getTargetException();
    }
  }
 
  protected void finalize()

  {
    // code from cm.release() goes here.
  }
 
}
 
 
in the lookup code 'return component;' can be replaced with:
 
  // may want to filter out the lifecycle interfaces...
  // they don't hurt, but it might be nice if they weren't
  // exposed to the client
  Class[] interfaces = component.getClass().getInterfaces();
 
  return java.lang.reflect.Proxy.newProxyInstance(
      classLoader,
      interfaces,
      new ReleasingProxy( component )
    );
 
[note: the ReleasingProxy will probably also need a reference to the
Container for doing the release]
 
Advantages:
 
- everything happens transparently to the client and the component
 
- the release code is only called after the client has lost all
references to the proxy (this actually makes it safer than using
cm.release())
 
Disadvantages:
 
- the release code is only called after the client has lost all
references to the proxy.
 
- relies on the VM's GC to return the component to the pool, and it is
unclear how long this will take.  [I don't know much about GC
implementations, but theoretically if there are no circular references
the reference count can become 0 and the VM can remove the object
immediately]
 
- requires JDK 1.3
 
- adds extra indirection to each component method call, and creates a
couple of extra objects on each lookup
 
Robert.


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


RE: Component Transactions

Posted by Robert <rm...@bull-enterprises.com>.
>From a user's perspective....

I like the lookup(String name) and I agree with Berin that 

lookup(ConnectionManager.ROLE, "SSL");

is 'cleaner' than

lookup(ConnectionManger.ROLE + "/SSL");

It might also be nice to have some Query like object in the future
and/or in more advanced containers.

As for Transactions, when I was teaching EJB courses, people had a hard
time with transactions and I would agree that one should really evaluate
if they are needed. If so, you might as well use EJB as that is what
their containers are designed for (among other things of course). I
guess it goes back to keeping it as simple as possible while still
having some flexibility.

- Robert

-----Original Message-----
From: Peter Donald [mailto:peter@apache.org] 
Sent: Thursday, June 06, 2002 7:47 PM
To: Avalon Developers List
Subject: Component Transactions

Hi,

Glad to see that Berin has finally come over to the dark side ;)

Two points to make (they may be familiar to you);

Object Role?
-------------------

Why do we need Object passed in as Role key? Why couldn't we have a
String 
passed in. And if we were going to pass in a string then why don't we 
concaternate the strings on clientside and have a simple interface such
as

public interface ServiceManager
{
   void lookup(String name) throws ComponentException;
   boolean exists( String name );
}

Note that I kept the ComponentException as it should only be raised in 
error condition.

Comonent "Transactions"
-------------------------------------

Several people have pointed that you will need to have what I am terming

"component transactions". ie You may have a top-level method M1 the
calls a 
worker method M2. However M2 may access resources R1, R2 & R3 that
should 
be released at the completion of M2. M1 may access R1, R2 & R3 later and
we 
want them to be available when M1 tries to access them. This is what I
will 
try to address here.

In the simple case (like in Phoenix) you can have container manage the 
Component resources and release when necessary and invalidate stale 
references (so that calls to stale objects raise 
InvalidStateExceptions).  In this case the transaction lifecycle looks
like

Transaction tied to lifecycle:
--------------------------------------------
Transaction.begin()
- startup component
- run component
- shutdown component
Transaction.end();
--------------------------------------------

If we assume that all Cocoon components can not create threads in their 
requests and that there is no nested-transactions then the following
could work

Transaction tied to thread:
--------------------------------------------
- startup component

For each request;
     Transaction.begin()
     - request()
     Transaction.end();

- shutdown component
--------------------------------------------

The complexity starts when you need to create a transaction inside
another 
transaction. ie You want to call M2 from M1. If you are familiar with
EJBs 
then you will recognize that this is where you would declare transaction

capabilities like NONE, REQUIRE_NEW, REQUIRED, SUPPORTS (and about 5
other 
attributes that I can never remember).

If you really need this capability (and I would encourage you to profile

before assuming you do) then I would encourage you to look at existing
Java 
Transaction API and see if you can get it to do your work. 
Rollback/completion would for our purposes means same thing (ie release 
aquired resources). You could even do insane things like generate
proxies 
that already supports EJB-like transaction attributes.

However if you are doing this sort of thing it really sounds like you
are 
mixing tiers and you should really consider moving you buisness logic to

another Container (be that EJB, Phoenix or something that just sits 
side-by-side to Cocoon).




--
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: Component Transactions

Posted by Berin Loritsch <bl...@apache.org>.
> From: Peter Donald [mailto:peter@apache.org] 
> 
> Hi,
> 
> Glad to see that Berin has finally come over to the dark side ;)
> 
> Two points to make (they may be familiar to you);
> 
> Object Role?
> -------------------
> 
> Why do we need Object passed in as Role key? Why couldn't we 
> have a String 
> passed in. And if we were going to pass in a string then why don't we 
> concaternate the strings on clientside and have a simple 
> interface such as
> 
> public interface ServiceManager
> {
>    void lookup(String name) throws ComponentException;
>    boolean exists( String name );
> }

I never said a Role should be an Object, but that we should have a
method for a String role and an Object hint for more complex queries.
That way we don't have to have MyCOmponent.ROLE + "/specific", we
keep the separate parts separate.

> 
> Note that I kept the ComponentException as it should only be 
> raised in 
> error condition.

Yeah, but it needs to be tested for.  If the only thing that can
go wrong on a *lookup* is that a component is not there, we should
make that exception a RuntimeException.  That way components who
assume everything to be OK (the usual case) don't have to do more
work than is necessary.  Others that want to catch the RuntimeException
can still do it.

This is done not by explicitly declaring the exception in the
interface, but in its javadocs:

public interface ServiceManager
{
    /** throws ComponentException if component is not available */
    Object lookup(String role);
    /** throws ComponentException if component is not available */
    Object lookup(String role, Object hint);

    boolean exists( String name ); // do we need more specific version?
}


<snip/>

I will look at the rest of the message in detail
offline.


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


Component Transactions

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

Glad to see that Berin has finally come over to the dark side ;)

Two points to make (they may be familiar to you);

Object Role?
-------------------

Why do we need Object passed in as Role key? Why couldn't we have a String 
passed in. And if we were going to pass in a string then why don't we 
concaternate the strings on clientside and have a simple interface such as

public interface ServiceManager
{
   void lookup(String name) throws ComponentException;
   boolean exists( String name );
}

Note that I kept the ComponentException as it should only be raised in 
error condition.

Comonent "Transactions"
-------------------------------------

Several people have pointed that you will need to have what I am terming 
"component transactions". ie You may have a top-level method M1 the calls a 
worker method M2. However M2 may access resources R1, R2 & R3 that should 
be released at the completion of M2. M1 may access R1, R2 & R3 later and we 
want them to be available when M1 tries to access them. This is what I will 
try to address here.

In the simple case (like in Phoenix) you can have container manage the 
Component resources and release when necessary and invalidate stale 
references (so that calls to stale objects raise 
InvalidStateExceptions).  In this case the transaction lifecycle looks like

Transaction tied to lifecycle:
--------------------------------------------
Transaction.begin()
- startup component
- run component
- shutdown component
Transaction.end();
--------------------------------------------

If we assume that all Cocoon components can not create threads in their 
requests and that there is no nested-transactions then the following could work

Transaction tied to thread:
--------------------------------------------
- startup component

For each request;
     Transaction.begin()
     - request()
     Transaction.end();

- shutdown component
--------------------------------------------

The complexity starts when you need to create a transaction inside another 
transaction. ie You want to call M2 from M1. If you are familiar with EJBs 
then you will recognize that this is where you would declare transaction 
capabilities like NONE, REQUIRE_NEW, REQUIRED, SUPPORTS (and about 5 other 
attributes that I can never remember).

If you really need this capability (and I would encourage you to profile 
before assuming you do) then I would encourage you to look at existing Java 
Transaction API and see if you can get it to do your work. 
Rollback/completion would for our purposes means same thing (ie release 
aquired resources). You could even do insane things like generate proxies 
that already supports EJB-like transaction attributes.

However if you are doing this sort of thing it really sounds like you are 
mixing tiers and you should really consider moving you buisness logic to 
another Container (be that EJB, Phoenix or something that just sits 
side-by-side to Cocoon).




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


Re: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Robert Mouat <ro...@mouat.net>.
It's been 6 hours so I'll try posting again...

<delurk/>

On Thu, 6 Jun 2002, Berin Loritsch wrote:

<snip/>

> interface ComponentManager
> {
>     Object lookup(String role);
>     Object lookup(String role, Object hint);
>     boolean exists(String role);
>     boolean exists(String role, Object hint);
> }
> 
> If you notice, there are four distinct differences from the current
> ComponentManger:

<snip/>

> 4) We remove the release() method altogether.

With a combination of dynamic proxies and the Object.finalize() method
it should be possible to use the VM's garbage collector to release a
component.  This would be transparent to both the client and the
component.

how this could work:

- cm.lookup() returns a dynamix proxy implementing the interfaces of
the desired component.  This proxy will pass all interface calls onto
the real component.

- neither the container nor the component manager keep a reference to
the proxy (they are allowed a weak reference -- but we want the VM's
GC to tell us when the client nolonger holds a reference to it.

- the client uses the component (transparently via the proxy).

- when the client loses all references to the proxy the GC will call
the finalize() mothod on the proxy.  This method will do what the
cm.release() method currently does.

[note: it is the proxy that gets garbage collected, not the component]


how the code might look:

class ReleasingProxy implements java.lang.reflect.InvocationHandler
{

  private Object component;

  public ReleasingProxy( Object o )
  {
    component = o;
  }

  public Object invoke( Object proxy, Method method, Object[] args ) 
    throws Throwable
  {
    try
    {
      return method.invoke( component, args );
    }
    catch ( InvocationTargetException e )
    {
      throw e.getTargetException();
    }
  }  

  protected void finalize()
  {
    // code from cm.release() goes here.
  }

}


in the lookup code 'return component;' can be replaced with:

  // may want to filter out the lifecycle interfaces...
  // they don't hurt, but it might be nice if they weren't
  // exposed to the client
  Class[] interfaces = component.getClass().getInterfaces();

  return java.lang.reflect.Proxy.newProxyInstance(
      classLoader,
      interfaces,
      new ReleasingProxy( component )
    );

[note: the ReleasingProxy will probably also need a reference to the
Container for doing the release]

Advantages:

- everything happens transparently to the client and the component

- the release code is only called after the client has lost all
references to the proxy (this actually makes it safer than using
cm.release())

Disadvantages:

- the release code is only called after the client has lost all
references to the proxy.

- relies on the VM's GC to return the component to the pool, and it is
unclear how long this will take.  [I don't know much about GC
implementations, but theoretically if there are no circular references
the reference count can become 0 and the VM can remove the object
immediately]

- requires JDK 1.3

- adds extra indirection to each component method call, and creates a
couple of objects each lookup

Robert.



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


Re: [Design] ContainerManager is under fire--let's find the best resolution

Posted by Robert Mouat <ro...@mouat.net>.
<delurk/>
 
On Thu, 6 Jun 2002, Berin Loritsch wrote:
 
<snip/>
 
> interface ComponentManager
> {
>     Object lookup(String role);
>     Object lookup(String role, Object hint);
>     boolean exists(String role);
>     boolean exists(String role, Object hint);
> }
>
> If you notice, there are four distinct differences from the current
> ComponentManger:
 
<snip/>
 
> 4) We remove the release() method altogether.
 
With a combination of dynamic proxies and the Object.finalize() method
it should be possible to use the VM's garbage collector to release a
component.  This would be transparent to both the client and the
component.
 
how this could work:
 
- cm.lookup() returns a dynamix proxy implementing the interfaces of
the desired component.  This proxy will pass all interface calls onto
the real component.
 
- neither the container nor the component manager keep a reference to
the proxy (they are allowed a weak reference -- but we want the VM's
GC to tell us when the client nolonger holds a reference to it.
 
- the client uses the component (transparently via the proxy).
 
- when the client loses all references to the proxy the GC will call
the finalize() mothod on the proxy.  This method will do what the
cm.release() method currently does.

[note: it is the proxy that gets garbage collected, not the component]
 
 
how the code might look:
 
class ReleasingProxy implements java.lang.reflect.InvocationHandler
{
 
  private Object component;
 
  public ReleasingProxy( Object o )
  {
    component = o;
  }
 
  public Object invoke( Object proxy, Method method, Object[] args )
    throws Throwable
  {
    try
    {
      return method.invoke( component, args );
    }
    catch ( InvocationTargetException e )
    {
      throw e.getTargetException();
    }
  }
 
  protected void finalize()

  {
    // code from cm.release() goes here.
  }
 
}
 
 
in the lookup code 'return component;' can be replaced with:
 
  // may want to filter out the lifecycle interfaces...
  // they don't hurt, but it might be nice if they weren't
  // exposed to the client
  Class[] interfaces = component.getClass().getInterfaces();
 
  return java.lang.reflect.Proxy.newProxyInstance(
      classLoader,
      interfaces,
      new ReleasingProxy( component )
    );
 
[note: the ReleasingProxy will probably also need a reference to the
Container for doing the release]
 
Advantages:
 
- everything happens transparently to the client and the component
 
- the release code is only called after the client has lost all
references to the proxy (this actually makes it safer than using
cm.release())
 
Disadvantages:
 
- the release code is only called after the client has lost all
references to the proxy.
 
- relies on the VM's GC to return the component to the pool, and it is
unclear how long this will take.  [I don't know much about GC
implementations, but theoretically if there are no circular references
the reference count can become 0 and the VM can remove the object
immediately]
 
- requires JDK 1.3
 
- adds extra indirection to each component method call, and creates a
couple of extra objects on each lookup
 
Robert.


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