avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Berin Loritsch <blorit...@apache.org>
Subject Re: Divergence from Avalon (was Re: [RT] Is Poolable Harmful?)
Date Wed, 09 Jan 2002 16:09:53 GMT
Paulo Gaspar wrote:


>>ExcaliburComponentManager/Selector have the three lifestyles: ThreadSafe,
>>SingleThreaded, Poolable.  The Poolable interface we all agree is 
>>not beneficial
>>to the system as a whole.  Also, having Components that are used only once
>>is not a good pattern as it adds undue stress on the garbage collecter and
>>only adds to the latency of looking up a Component.  Therefore the point
>>of the original thread was to merge SingleThreaded and Poolable so that
>>all SingleThreaded Components are pooled.
>>
>  
> That may make sense for Avalon but I am not sure it makes sense for my 
> project. It would be like pooling most objects you create in a Servlet.
> 
> The SingleThreaded components I have that are not pooled are very light
> anyway. In the whole picture of the many objects created and destroyed
> to process a request they are not a representative extra load for the
> garbage collector.


Modern JVM's are very efficient when all you are doing is creating a new
instance of a small final class (as close as Java will ever get to a C
'struct').  The problem occurs when the cost of creating a new Component
also involves running it through a lifecycle, or it is an expensive
resource like a Database Connection object.



>>>  There is no "DefaultComponentFactory". Each type of component has its
>>>  specific factory. This factory takes care of configuration too.
>>>
>>
>>In essence, you have merged the ComponentHolder and ComponentFactory into
>>one class.  The ComponentFactory gives the Configuration 
>>information to the Component.  This works well in most situations.
>>
> 
> ComponentHolder? What ComponentHolder? I do not know that one!


Sorry, that was the old name for ComponentHandler.  They are equivalent.



> If it is a "ComponentHandler", I keep having those. My names are different
> but you could call them:
>   - ThreadSafeComponentHandler  
>   - SingleThreadedComponentHandler


Yup.  That's what I have as well.



> Poolable objects have their pool wrapped by a factory and are handled by
> the SingleThreadedComponentHandler.


A pool wrapped by a factory?  How does that work?  I am used to seeing
a Pool use a Factory to generate instances.  If you are referring to the
Factory pattern (Design Patterns, GoF), then I can see the Pool being
part of the "factory".

I think this may be the cause of my confusion.



>>>  (Much of this configuration cab be eased using a "configuration bean"
>>>   a Configurer and a Converter, like Peter did on Ant Myrmidon proposal
>>>   ...although my code already went a lot beyond what was there some 3 
>>>   months ago.)
>>>
>>
>>:)  This is one of the things I am working on.  A completely 
>>managed solution.
>>By using a number of "Managers" all working independantly on 
>>different parts
>>of the system.  That way, the users of the Managed Container only have to
>>worry about the Components and how they are mapped together in a 
>>system--all
>>reconfiguration and logger remapping are done automatically.
>>
> 
> That is too complex for me to consider at the moment but I am very curious
> about those new dynamic developments, like the with run-time management/
> reconfiguration and saving the current configuration back to disk.
> 
> Probably I will end up finding some use for those ideas too.
> =:o)


I am still formulating the plans in my head.



>>Perhaps this goes beyond what you are thinking of.  However, such a managed
>>system is able to make expensive decisions about the most efficient way to
>>allocate resources asynchronously from the rest of the system.  That way
>>latencies involved in lookup and releasing of components are minimized to
>>simple get() and put() calls on a Map.
>>
> 
> This paragraph is not clear to me.
> Why will that improve latencies so much?


Because the management is no longer performed synchronously.  Instead of managing
pool sizes as objects are requested and returned to the pool, they are managed by
an asynchronous process.  That asynchronous process will have the intelligence to
predict the optimal pool size so that all get() requests pass without wasting
resources.

Also, for a cache implementation example, the asynchronous process will check the
validity of the entries in the Cache, and automatically purge stale entries.  That
way the Cache does not have to perform that check synchronously.

When management of resources are moved outside of the critical path of execution,
the critical path is shorter and simpler.  Shorter and simpler == faster.



>>>  My "ComponentHandler" still takes care of lifecycle management 
>>>  operations and strategies, like:
>>>    - Initializing, starting, stopping, disposing, etc.
>>>    - Using only one instance for thread safe components and 
>>>      always a new instance for the others.
>>>
>>
>>That is the implementer's perogative on how they want to manage 
>>their system
>>or define Components.  However, if your system does not work with 
>>any Avalon
>>Component, then you have lost the ability to use a number of well tested
>>Components.  Hopefully you have not lost that ability.
>>
> 
> Most of my components are not from the Avalon universe, hence many 
> of my choices. 


I see.



> Even with components that exist at Avalon, sometimes I needed 
> something different. I ended up building my own pool an my own 
> connection pool in order to have better control over its behavior
> and to better control its resources.


Hmmm.   What additional control do you need?


>>It seems like alot of work for a Component writer to create a new factory
>>for each Component.  I beleive that slows development time unnecessarily.
>>By having one generic ComponentFactory, you can focus on more important
>>issues like Component interaction, and how it should handle when 
>>Components are not available.
>>
> 
> Actually not. The component writer just ends up moving the configuration 
> code from the component to its factory, and thanks to the auto-configuration
> functionality, that code is much simpler.
> 
> Since that code works based on introspection (like in Ant, as I already 
> mentioned) I even use a separate bean (or just an object with fields) to
> be introspected and receive the configuration information.
> 
> I end up with 3 classes:
>  - The component;
>  - The factory;
>  - The configuration bean which is usually an inner class of the factory.
> 
> But overall the code is much simpler/shorter than typical Avalon code.
> 
> And I can use 3rd party / isolated components without modifying them.


Can you post a code example.  That might help me understand where you are
coming from.




>>>>And if your Role interface extends Component, you have the same
>>>>convenience--while maintaining the protection that forces you to
>>>>separate data and the interface to get the data.
>>>>
>>>>
>>>Again, the above mentioned factory makes my aware of that.
>>>
>>I won't belabor this point.  I just know that a "ComponentManager"
>>that deals with Objects is open to abuse by less disciplined people
>>than yourself.  For a framework, I am not convinced if it is
>>proper.  Of course, I am open to understanding the motivation for
>>it.
>>
> 
> I think that just implementing the Component interface makes no much
> difference. It is just a marker.


Probably, and Peter surprised me when he mentioned he was in favor of
removing Component.




> Maybe we are talking about different things?
> 
> However, I have a role interface which ends up being validated, of 
> course. Maybe that is what you mean.


When I talk about a Component's interface, this is precisely what I
am referring to.



> My roles configuration xml format is quite different but it includes
> both the factory class and the role class, this last one being the 
> interface of the object built by the factory.


That is only a configuration issue.




>>As to Component Management, we have discussed many ideas before we came up
>>with what we have now.  Among them were JNDI, strict 
>>ComponentManager (i.e.
>>it was considered wrong to have multiple components for a role),
>>NamedComponentManager (with your lookup by role and name), and the current
>>ComponentManager/Selector approach.
>>
> 
> I went trough that process too. JNDI included.
> =:o)
> 
> 
> 
>>Many times, use has tempered our views of the world.  Our 
>>personal experience
>>deems what is more natural for us to use, and how we view our 
>>world.  Cocoon
>>started out down the path of the NamedComponentManager.  I don't think it
>>was correct for the NamedComponent interface, but it did have a certain
>>simplicity.
>>
>>The question arose when we have n-dimensional needs for gaining 
>>access to a
>>Component.  For instance, a ComponentManager addresses one 
>>dimension: role.
>>ComponentSelector defines a purposely loose contract so that you can use
>>any object or query objects to address all the extra dimensions that might
>>arise for future systems.
>>
> 
> I think I am getting it.
> 
> However, I still see the Selectors as a way of having more than one 
> implementation for the same role, but I have a different problem: I
> have different implementations and different instances.


The ComponentSelector (in Excalibur) works exactly like the ComponentManager.
In effect, you have different instances of the same implementations (even
with different configurations per instance).  It works like what you need.
You just don't like the API :).




>>Another interesting approach is the use of a Query object to lookup the
>>required component.  The one Query object addresses as many dimensions as
>>is necessary in the system to lookup the correct component.  This 
>>can include
>>role, name, locale, and session information into the one lookup request.
>>
> 
> VERY interesting idea.
> 
> The query object can even use a task/request Context for the locale/user
> data.


Precisely :)

This is what makes the concept so powerful.



>>>It is because my problem domain is so different from Avalon's that I 
>>>ended up finding that a lot could be made much simpler by changing 
>>>the way the ComponentManager related stuff works.
>>>
>>And that is why I want to learn from you.
>>
> 
> Well, I am already learning from you.
> =:o)


It's a mutual thing.



>>>That added complexity to the ComponentManager (still not very big) but
>>>simplified a lot the overall project.
>>>
>>>
>>>It is just one of those things that you have to play a lot with to
>>>understand why.
>>>
>>Well a short history of the decision process would help alot more than
>>playing with it.
>>
> 
> In terms of interface the main difference is having the name and the 
> role. Actually I have "role" (interface), "type" (implementation) and
> "name", but only "role" and "name" are lookup keys.
> 
> The other big difference is the "token" based resource management. The
> one that allows me to ensure that all components requested for a task
> are released at its end:
> 
> // start processing request  
>   obj1 = cm.get(token, role1, name1);
>   obj1 = cm.get(token, role2, name2);  
>   obj1 = cm.get(token, role3, name3);
> ....
> 
> // finish processing request
>   cm.release(token);


What are your perceived advantages to using the Token?  I say perceived,
because in order for them to be considered real they have to be proven.
Many times, perceived advantage is just as important as real advantage.

However, we may find that token is a step in the right direction, or
maybe not.  I just want to know why you happen to like it.



>>>Notice that I followed a different approach than Cocoon, where the 
>>>sitemap has almost nothing to do with the ComponentManager.
>>>
>>>In my implementation, the sitemap is stored in the ComponentManager.
>>>Overall, my implementation is much, much, much simpler.
>>>
>>Cocoon's Sitemap is stored in a ComponentManager as well.  It just needs
>>access to a large number of other Components.
>>
> 
> Ops! Where? 
> Is it the new tree walking stuff?


No.


> 
> It was compiled, right? (I only looked at Cocoon2.)


Yes.  The Sitemap is a Component that happens to be Compiled and loaded
dynamically by the ClassLoader.  While it is being used, it behaves
exactly like any other component.





-- 

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


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


Mime
View raw message