You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by Berin Loritsch <bl...@apache.org> on 2003/10/21 19:48:22 UTC

Percieved Pooling Problems

Using aliteration here...

Seriously, I can tell that Stephen is trying to raise an issue that he feels
strongly about.  I don't want to ignore them, but I am having problems
understanding his point.  So, this is my attempt at restating what I *think*
he may be getting at.

Transient components vs Singleton components
--------------------------------------------

Transient components return a different instance each time you ask for them.
Pooled or not, that is how the container treats these components.  Is there
a potential issue here?  Yes.  In fact, it is already a known issue.  It has
to do with the policy of retreiving and using the components.  Let us assume
we have a Singleton component named SinglePipeline and a pair of transient
components named Input and Output.

The known issue is demonstrated by this code:

class SinglePipeline implements Pipeline, Serviceable, Disposable
{
     private ServiceManager manager;
     private Input in;
     private Output out;

     public void service(ServiceManager manager) throws ServiceException
     {
         this.manager = manager;
         in = (Input) manager.lookup("in");
         out = (Output) manager.lookup("out");
     }

     public void dispose()
     {
         manager.release(in);
         manager.release(out);
         manager = null;
     }

     public void process(Properties withParams)
     {
         out.setProperties(withParams);
         in.setProperties(withParams);
         in.setOutput(out);
         in.execute();
     }
}

As you can see, these transient components are held for the life of the
singleton pipeline.  This is a known problem, and affects frameworks like
Cocoon.  However, this is not pooled component specific.

Now, if the component was rewritten like this:

class SinglePipeline implements Pipeline, Serviceable
{
     private ServiceManager manager;

     public void service(ServiceManager manager) throws ServiceException
     {
         this.manager = manager;
     }

     public void process(Properties withParams)
     {
         Input in = null;
         Output out = null;

         try
         {
             in = (Input) manager.lookup("in");
             out = (Output) manager.lookup("out");

             out.setProperties(withParams);
             in.setProperties(withParams);
             in.setOutput(out);
             in.execute();
         }
         finally
         {
             manager.release(in);
             manager.release(out);
         }
     }
}

We regain a system that is used as the components were *intended*.  Whether
pooled or not, the transient components are used as transient components.
There is a known disconnect that components are not aware of the implementation
details of how a particular component type is intended to be used.  In fact,
in some cases it might very well depend on the implementation of the component,
and not the type of component.  I have seen examples of both of these.

I don't think this is what Stephen is getting at, although it might be part of
the picture.

Back to the Pooled Problems
---------------------------
Some of the problem I can tell has to do with the Resettable
interface.  The fact that Resettable/Recyclable etc. is not part of the
Framework interface means that we can't easily switch out pooling
implementations at will.  Even if we make the pooling implementation backwards
compatible (as is the case with MPool), should another pooling implementation
come along, how do we make sure that the component gets back to a usable state?

I think what you are getting at, Stephen (sorry if I sound like I am picking
on you), seems to be the predictability of pooling semantics--regardless of
implementation.

In essence, it is not so much a problem if we have a simple method that the
container calls to let the component know it has to clear out any state
information--it is that there is no official standard for it.

The drastic conclusion that you came up with is that because there is no
absolute standard, then there can be no cross-container predictability unless
we use the same implementation details for the pooling code.  To this I can
agree.  However, I think we have differing solutions to the problem.  The
lowest cost solution would be to add a new interface that has the release
semantics of resetting the component before it is accessed again.  That would
make it part of the component/service contracts--and we can adapt any pool
implementation to satisfy it.

Would that be enough--at least in the short term?

-- 

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



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


Re: Percieved Pooling Problems

Posted by Stephen McConnell <mc...@apache.org>.

Berin Loritsch wrote:

> Stephen McConnell wrote:
>
>
>>
>> I'm not really following the short term comment - if there is a short 
>> term solution it implies that there is a long ter solution which in 
>> my understanding has not been presented. If I look at Excalibur event 
>> mpool I have some contracts which after refactoring relative to the 
>> meta package could become part of the framework lifecycle model - and 
>> as such, influsnece lifestyle decisions concering component 
>> recycling.  If I look at the Turbine Fulcrum package there is an 
>> equivalent set of of interfaces (pools, recycling, etc.).  At the 
>> same time I wondering to myself if we are simply overloading lookup 
>> with too many semantics?  What if you have an A5 interface that 
>> seperated pooled and non-pooled obect lookup? I.e. explicit 
>> understanding that transient object dependencies are not the same as 
>> singleton dependecies.  I don't the answer just yet - but from a 
>> purist architectural point of view - something smells wrong in the 
>> corner of the world.
>>
>
> My particular solution would be the introduction of the Resettable or 
> equivalent
> interface.  You seemed to be hinting at something alot more complex.  
> So, I was
> leaving the door open for you to expound on it.  ;P 


Honestly - I don't have something in mind.  I'm just bumping into walls 
with respect to the component/container contract when dealing with 
pooled components.  The rub is all about lifestyle/lifecycle assumptions 
and how that impacts the component/container contracts. I need more time 
to think about this before providing anything useful.

Steve.

-- 

Stephen J. McConnell
mailto:mcconnell@apache.org




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


Re: Percieved Pooling Problems

Posted by Berin Loritsch <bl...@apache.org>.
Stephen McConnell wrote:


> 
> I'm not really following the short term comment - if there is a short 
> term solution it implies that there is a long ter solution which in my 
> understanding has not been presented. If I look at Excalibur event mpool 
> I have some contracts which after refactoring relative to the meta 
> package could become part of the framework lifecycle model - and as 
> such, influsnece lifestyle decisions concering component recycling.  If 
> I look at the Turbine Fulcrum package there is an equivalent set of of 
> interfaces (pools, recycling, etc.).  At the same time I wondering to 
> myself if we are simply overloading lookup with too many semantics?  
> What if you have an A5 interface that seperated pooled and non-pooled 
> obect lookup? I.e. explicit understanding that transiwent object 
> dependencies are not the same as singleton dependecies.  I don;t the 
> answer just yet - but from a purist architectural point of view - 
> something smells wrong in the corner of the world.
> 

My particular solution would be the introduction of the Resettable or equivalent
interface.  You seemed to be hinting at something alot more complex.  So, I was
leaving the door open for you to expound on it.  ;P

As to A5 lookup semantics--I would prefer something much simpler.  I like having
one interface for everything.  You shouldn't have to know what is going on.

-- 

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


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


Re: Percieved Pooling Problems

Posted by Stephen McConnell <mc...@apache.org>.
[with corrections]


Stephen McConnell wrote:

>
>
> Berin Loritsch wrote:
>
>> Using aliteration here... 
>
>
>
> Perhaps a Portability Problem P[r]oliferated by Particular Past 
> Practices?
>
> ;-)
>
>>
>>
>> Seriously, I can tell that Stephen is trying to raise an issue that 
>> he feels
>> strongly about.  I don't want to ignore them, but I am having problems
>> understanding his point.  
>
>
>
> My son was saying exactly the same thing to me yesterday - but we 
> sorting t[h]ings out at about 4:15 in the morning!
>
>
>> So, this is my attempt at restating what I *think*
>> he may be getting at.
>>
>> Transient components vs Singleton components
>> --------------------------------------------
>>
>> Transient components return a different instance each time you ask 
>> for them.
>> Pooled or not, that is how the container treats these components.  Is 
>> there
>> a potential issue here?  Yes.  In fact, it is already a known issue.  
>> It has
>> to do with the policy of retreiving and using the components.  Let us 
>> assume
>> we have a Singleton component named SinglePipeline and a pair of 
>> transient
>> components named Input and Output.
>>
>> The known issue is demonstrated by this code:
>>
>> class SinglePipeline implements Pipeline, Serviceable, Disposable
>> {
>>     private ServiceManager manager;
>>     private Input in;
>>     private Output out;
>>
>>     public void service(ServiceManager manager) throws ServiceException
>>     {
>>         this.manager = manager;
>>         in = (Input) manager.lookup("in");
>>         out = (Output) manager.lookup("out");
>>     }
>>
>>     public void dispose()
>>     {
>>         manager.release(in);
>>         manager.release(out);
>>         manager = null;
>>     }
>>
>>     public void process(Properties withParams)
>>     {
>>         out.setProperties(withParams);
>>         in.setProperties(withParams);
>>         in.setOutput(out);
>>         in.execute();
>>     }
>> }
>>
>> As you can see, these transient components are held for the life of the
>> singleton pipeline.  This is a known problem, and affects frameworks 
>> like
>> Cocoon.  
>
>
>
> OK.
> Just for clarification - the above issue is related to the fact that 
> the pipeline is making lifestyle assumptions about the se[r]vices it 
> is using.  These lifestyle assumptions are not declared in the service 
> directive - and and as such - the pipeline is a wreck simply because 
> it has bee supplied with services that did not match the semantic 
> assumptions of the pipeline impleme[n]tation.
>
> If my understanding is correct - what you are saying is that lifestyle 
> is a property of a dependecy.
>
>> However, this is not pooled component specific.
>
>
>
> Well clearly you have just demonstrated a case where this is an issue 
> in a singleton abstraction.  Which suggests that this is an aspect of 
> a dependency.
>
>>
>> Now, if the component was rewritten like this:
>>
>> class SinglePipeline implements Pipeline, Serviceable
>> {
>>     private ServiceManager manager;
>>
>>     public void service(ServiceManager manager) throws ServiceException
>>     {
>>         this.manager = manager;
>>     }
>>
>>     public void process(Properties withParams)
>>     {
>>         Input in = null;
>>         Output out = null;
>>
>>         try
>>         {
>>             in = (Input) manager.lookup("in");
>>             out = (Output) manager.lookup("out");
>>
>>             out.setProperties(withParams);
>>             in.setProperties(withParams);
>>             in.setOutput(out);
>>             in.execute();
>>         }
>>         finally
>>         {
>>             manager.release(in);
>>             manager.release(out);
>>         }
>>     }
>> }
>>
>> We regain a system that is used as the components were *intended*.  
>> Whether
>> pooled or not, the transient components are used as transient 
>> components.
>> There is a known disconnect that components are not aware of the 
>> implementation
>> details of how a particular component type is intended to be used.  
>> In fact,
>> in some cases it might very well depend on the implementation of the 
>> component,
>> and not the type of component.  I have seen examples of both of these. 
>
>
>
> If I understand correctly - this is an example of a coding pra[c]tice 
> the negates the necessity to express and assumption relating to 
> lifestyle within a dependency.  I.e. the impl[e]mentation descri[b]ed 
> above [is] lifestyle independent.
>
>>
>>
>> I don't think this is what Stephen is getting at, although it might 
>> be part of
>> the picture. 
>
>
>
> I'm learning as we go.
>
>>
>>
>> Back to the Pooled Problems
>> ---------------------------
>> Some of the problem I can tell has to do with the Resettable
>> interface.  The fact that Resettable/Recyclable etc. is not part of the
>> Framework interface means that we can't easily switch out pooling
>> implementations at will.  Even if we make the pooling implementation 
>> backwards
>> compatible (as is the case with MPool), should another pooling 
>> implementation
>> come along, how do we make sure that the component gets back to a 
>> usable state? 
>
>
>
> Yep - that is the issue I was driving at.
>
>>
>>
>> I think what you are getting at, Stephen (sorry if I sound like I am 
>> picking
>> on you), seems to be the predictability of pooling 
>> semantics--regardless of
>> implementation. 
>
>
>
> Don't worry about me - its the specification of behaviour and assumed 
> semantics that we are picking at ..i.e. in the context "predictability 
> of pooling semantics".
>
>>
>>
>> In essence, it is not so much a problem if we have a simple method 
>> that the
>> container calls to let the component know it has to clear out any state
>> information--it is that there is no official standard for it. 
>
>
>
> Yes - because it is something that needs to be understood at the 
> formal lifecycle level.  I.e. its not a lifestyle question.
>
>>
>> The drastic conclusion that you came up with is that because there is no
>> absolute standard, then there can be no cross-container 
>> predictability unless
>> we use the same implementation details for the pooling code.  To this 
>> I can
>> agree.  However, I think we have differing solutions to the problem.  
>> The
>> lowest cost solution would be to add a new interface that has the 
>> release
>> semantics of resetting the component before it is accessed again.  
>> That would
>> make it part of the component/service contracts--and we can adapt any 
>> pool
>> implementation to satisfy it.
>>
>> Would that be enough--at least in the short term? 
>
>
>
> I'm not really following the short term comment - if there is a short 
> term solution it implies that there is a long ter[m] solution which in 
> my understanding has not been presented. If I look at Excalibur event 
> mpool I have some contracts which after refactoring relative to the 
> meta package could become part of the framework lifecycle model - and 
> as such, influ[e]n[c]es lifestyle decisions concering component 
> recycling.  If I look at the Turbine Fulcrum package there is an 
> equivalent set of of interfaces (pools, recycling, etc.).  At the same 
> time I wondering to myself if we are simply overloading lookup with 
> too many semantics?  What if you have an A5 interface that sep[a]rated 
> pooled and non-pooled ob[j]ect lookup? I.e. explicit understanding 
> that transient object dependencies are not the same as singleton 
> depende[n]cies.  I don't [have] the answer just yet - but from a 
> purist architectural point of view - something smells wrong in th[is] 
> corner of the world.


(and it's not just my spelling)

;-)

>
> Cheers, Steve.
>
>>
>>
>

-- 

Stephen J. McConnell
mailto:mcconnell@apache.org




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


Re: Percieved Pooling Problems

Posted by Stephen McConnell <mc...@apache.org>.

Berin Loritsch wrote:

> Using aliteration here... 


Perhaps a Portability Problem Poliferated by Particular Past Practices?

;-)

>
>
> Seriously, I can tell that Stephen is trying to raise an issue that he 
> feels
> strongly about.  I don't want to ignore them, but I am having problems
> understanding his point.  


My son was saying exactly the same thing to me yesterday - but we 
sorting tings outat about 4:15 in the morning!


> So, this is my attempt at restating what I *think*
> he may be getting at.
>
> Transient components vs Singleton components
> --------------------------------------------
>
> Transient components return a different instance each time you ask for 
> them.
> Pooled or not, that is how the container treats these components.  Is 
> there
> a potential issue here?  Yes.  In fact, it is already a known issue.  
> It has
> to do with the policy of retreiving and using the components.  Let us 
> assume
> we have a Singleton component named SinglePipeline and a pair of 
> transient
> components named Input and Output.
>
> The known issue is demonstrated by this code:
>
> class SinglePipeline implements Pipeline, Serviceable, Disposable
> {
>     private ServiceManager manager;
>     private Input in;
>     private Output out;
>
>     public void service(ServiceManager manager) throws ServiceException
>     {
>         this.manager = manager;
>         in = (Input) manager.lookup("in");
>         out = (Output) manager.lookup("out");
>     }
>
>     public void dispose()
>     {
>         manager.release(in);
>         manager.release(out);
>         manager = null;
>     }
>
>     public void process(Properties withParams)
>     {
>         out.setProperties(withParams);
>         in.setProperties(withParams);
>         in.setOutput(out);
>         in.execute();
>     }
> }
>
> As you can see, these transient components are held for the life of the
> singleton pipeline.  This is a known problem, and affects frameworks like
> Cocoon.  


OK.
Just for clarification - the above issue is related to the fact that the 
pipeline is making lifestyle assumptions about the sevices it is using.  
These lifestyle assumptions are not declared in the service directive - 
and and as such - the pipeline is a wreck simply because it has bee 
supplied with services that did not match the semantic assumptions of 
the pipeline implemetation.

If my understanding is correct - what you are saying is that lifestyle 
is a propertly of a dependecy.

> However, this is not pooled component specific.


Well clearly you have just demonstrated a case where this is an issue in 
a singletone abstraction.  Which suggests that this is an aspect of a 
dependency.

>
> Now, if the component was rewritten like this:
>
> class SinglePipeline implements Pipeline, Serviceable
> {
>     private ServiceManager manager;
>
>     public void service(ServiceManager manager) throws ServiceException
>     {
>         this.manager = manager;
>     }
>
>     public void process(Properties withParams)
>     {
>         Input in = null;
>         Output out = null;
>
>         try
>         {
>             in = (Input) manager.lookup("in");
>             out = (Output) manager.lookup("out");
>
>             out.setProperties(withParams);
>             in.setProperties(withParams);
>             in.setOutput(out);
>             in.execute();
>         }
>         finally
>         {
>             manager.release(in);
>             manager.release(out);
>         }
>     }
> }
>
> We regain a system that is used as the components were *intended*.  
> Whether
> pooled or not, the transient components are used as transient components.
> There is a known disconnect that components are not aware of the 
> implementation
> details of how a particular component type is intended to be used.  In 
> fact,
> in some cases it might very well depend on the implementation of the 
> component,
> and not the type of component.  I have seen examples of both of these. 


If I understand correctly - this is an example of a coding pratice the 
negates the necessity to express and assumption relating to lifestyle 
within a dependency.  I.e. the inmplmentation descriped above if 
lifestyle independent.

>
>
> I don't think this is what Stephen is getting at, although it might be 
> part of
> the picture. 


I'm learning as we go.

>
>
> Back to the Pooled Problems
> ---------------------------
> Some of the problem I can tell has to do with the Resettable
> interface.  The fact that Resettable/Recyclable etc. is not part of the
> Framework interface means that we can't easily switch out pooling
> implementations at will.  Even if we make the pooling implementation 
> backwards
> compatible (as is the case with MPool), should another pooling 
> implementation
> come along, how do we make sure that the component gets back to a 
> usable state? 


Yep - that is the issue I was driving at.

>
>
> I think what you are getting at, Stephen (sorry if I sound like I am 
> picking
> on you), seems to be the predictability of pooling 
> semantics--regardless of
> implementation. 


Don't worry about me - its the specification of behaviour and assumed 
semantics that we are picking at ..i.e. in the context "predictability 
of pooling semantics".

>
>
> In essence, it is not so much a problem if we have a simple method 
> that the
> container calls to let the component know it has to clear out any state
> information--it is that there is no official standard for it. 


Yes - because it is something that needs to be understood at the formal 
lifecycle level.  I.e. its not a lifestyle question.

>
> The drastic conclusion that you came up with is that because there is no
> absolute standard, then there can be no cross-container predictability 
> unless
> we use the same implementation details for the pooling code.  To this 
> I can
> agree.  However, I think we have differing solutions to the problem.  The
> lowest cost solution would be to add a new interface that has the release
> semantics of resetting the component before it is accessed again.  
> That would
> make it part of the component/service contracts--and we can adapt any 
> pool
> implementation to satisfy it.
>
> Would that be enough--at least in the short term? 


I'm not really following the short term comment - if there is a short 
term solution it implies that there is a long ter solution which in my 
understanding has not been presented. If I look at Excalibur event mpool 
I have some contracts which after refactoring relative to the meta 
package could become part of the framework lifecycle model - and as 
such, influsnece lifestyle decisions concering component recycling.  If 
I look at the Turbine Fulcrum package there is an equivalent set of of 
interfaces (pools, recycling, etc.).  At the same time I wondering to 
myself if we are simply overloading lookup with too many semantics?  
What if you have an A5 interface that seperated pooled and non-pooled 
obect lookup? I.e. explicit understanding that transiwent object 
dependencies are not the same as singleton dependecies.  I don;t the 
answer just yet - but from a purist architectural point of view - 
something smells wrong in the corner of the world.

Cheers, Steve.

>
>

-- 

Stephen J. McConnell
mailto:mcconnell@apache.org




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