You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@excalibur.apache.org by Carsten Ziegeler <cz...@s-und-n.de> on 2004/06/24 09:00:48 UTC
[RT] About proxies and pooling
Ok, let's start thinking about some "new" things :)
(Actually this is not new but who cares?)
a) Proxy Handling in Fortress
Currently it's possible to define/configure if/how Fortress
is creating a proxy for a component. I'm wondering if this
flexibility is really required.
I think we should always create a proxy.
There are imho three reasons:
- security: if you create a proxy, the client can't cast
the component to the implementation class.
- Performance/remove a bottle neck: currently without a proxy
all components are stored on lookup in a big hash map together
with their handler and on release the handler is taken out the
map to properly release the component. So this map is a bottle neck
for multi-threaded apps.
With a proxy we can store the handler in the proxy and remove
this bottle neck. Actually this is already implemented in Fortress
if you use proxies :)
- Better Support for non thread-safe components. See below.
Now, by always creating a proxy we can remove/clean up some code
in Fortress and it gets a little bit smaller as well :)
WDYT?
b) Pooling (or handling of non thread-safe components)
A problem that always bites me is that you have to know if a component
is thread safe or not. For example, if you have a thread safe component
that uses other components, then you can't simply lookup this component
in service()/compose(). You can only safely do this, if the component
implementation you look up is thread safe as well.
If it is pooled or single threaded you have to lookup/release this component
each time you use it.
So, if you really want to develop a multi-threaded app, you either have
to know which components are thread safe or not or you have to lookup
release a component each time you use it. I think both solutions are not
very nice :)
Now, there have been a lot of discussions about this topic. For example,
we had suggestions that all components should be thread safe. Even if
this would be an option for the future, it's just this: "the future". We
currently have a lot of apps out there that use pooled and single threaded
components.
Similar is the discussion about pooling components yourself or let the JVM
pool them for you. This way or that way: the components are pooled but not
thread safe.
So, a rather long introduction for the problem :) Now, I think one solution
for this
is to say "let's pretend that all components are thread safe". So, the basic
idea is to create a proxy for each component that ensures that the use
of the underlying component is in a thread safe way (and this is the third
reason for proxies).
For example, if you're using a pooled component, you get a proxy that during
one request, fetches a component from a pool - if the component is used -
and releases the component when the request is finished.
Therefore you need to notify the container when a request starts and
finishs.
During the request the pooled components are stored somewhere (thread local
for example) and when the request is finished they are released.
This mechanism is only required for pooled or single threaded components,
thread safe components don't need this extra behaviour.
This would allow the client to lookup a component in service() and just
use it and the underlying logic takes care that you don't get threading
problems.
I conclude from the docs, that e.g. HiveMind is doing it this way.
WDYT?
Carsten
Carsten Ziegeler
Open Source Group, S&N AG
http://www.osoco.net/weblogs/rael/
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@excalibur.apache.org
For additional commands, e-mail: dev-help@excalibur.apache.org
Apache Excalibur Project -- URL: http://excalibur.apache.org/
RE: [RT] About proxies and pooling
Posted by Carsten Ziegeler <cz...@s-und-n.de>.
Peter Donald wrote:
>
> Carsten Ziegeler wrote:
> > During the request the pooled components are stored
> somewhere (thread
> > local for example) and when the request is finished they
> are released.
> >
> > This mechanism is only required for pooled or single threaded
> > components, thread safe components don't need this extra behaviour.
> >
> > This would allow the client to lookup a component in service() and
> > just use it and the underlying logic takes care that you don't get
> > threading problems.
>
> This is basically the way that I tend to do things and the
> way I suggested when Cocoon2 was still in it's embryonic
> stages. There were basically three complaints about it IIRC
> (Although Berin may be able to remember more?). One basically
> translated into whats now called the "too much magic"
> argument,
:)
> the other was performance and the last was that it
> disabled "advanced resource control". The advanced resource
> control could be summed up in the following scenario;
>
> //Start Job
> for( int i = 0; i < 100; i++ )
> {
> final X x =
> rm.lookupResource( X.class.getName() + "/" + i );
> use( x );
> }
> //End Job
>
> The problem is that under the naive implementaiton of the
> proxy magic you would end up maintaining 100 references to
> underlying resource while you were performing the job whereas
> in this scenario you only need to access 1 at any one time
> (and up to 99 sit marked as used but actually idle).
>
> My suggestion was that you allow a release mechanism but dont
> make it required by default. ie In DNA we have a
> ReleaseUtil.release() for just this purpose.
>
Ah, ok, now I think this example is a little bit misleading.
I don't want to change the lookup/release mechanism. This means,
you can lookup/release a component at any time, so you could
release the component inside the look.
For example, with the components used to assemble a Cocoon pipeline
during request execution, you would exactly do it the way it's
currently done: lookup when required and release immediately.
I'm trying to aim at areas where your component assembly is more
static: for example a managing component needs some other component
for the whole lifetime. And in these cases I think the mechanism
is great - but it shouldn't be an auto-release mechanism for
all components.
Carsten
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@excalibur.apache.org
For additional commands, e-mail: dev-help@excalibur.apache.org
Apache Excalibur Project -- URL: http://excalibur.apache.org/
Re: [RT] About proxies and pooling
Posted by Peter Donald <pe...@realityforge.org>.
Carsten Ziegeler wrote:
> During the request the pooled components are stored somewhere (thread local
> for example) and when the request is finished they are released.
>
> This mechanism is only required for pooled or single threaded components,
> thread safe components don't need this extra behaviour.
>
> This would allow the client to lookup a component in service() and just
> use it and the underlying logic takes care that you don't get threading
> problems.
This is basically the way that I tend to do things and the
way I suggested when Cocoon2 was still in it's embryonic
stages. There were basically three complaints about it IIRC
(Although Berin may be able to remember more?). One
basically translated into whats now called the "too much
magic" argument, the other was performance and the last was
that it disabled "advanced resource control". The advanced
resource control could be summed up in the following scenario;
//Start Job
for( int i = 0; i < 100; i++ )
{
final X x =
rm.lookupResource( X.class.getName() + "/" + i );
use( x );
}
//End Job
The problem is that under the naive implementaiton of the
proxy magic you would end up maintaining 100 references to
underlying resource while you were performing the job
whereas in this scenario you only need to access 1 at any
one time (and up to 99 sit marked as used but actually idle).
My suggestion was that you allow a release mechanism but
dont make it required by default. ie In DNA we have a
ReleaseUtil.release() for just this purpose.
--
Cheers,
Peter Donald
*---------------------------------------------*
| "The only way to discover the limits of the |
| possible is to go beyond them into the |
| impossible." -Arthur C. Clarke |
*---------------------------------------------*
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@excalibur.apache.org
For additional commands, e-mail: dev-help@excalibur.apache.org
Apache Excalibur Project -- URL: http://excalibur.apache.org/
RE: [RT] About proxies and pooling
Posted by Carsten Ziegeler <cz...@s-und-n.de>.
Berin Loritsch wrote:
>
> This is the rough equivalent of what BCEL generates:
>
> class BCELGeneratedProxy implements A
> {
> private final A m_proxy;
>
> public BCELGeneratedProxy(A proxy)
> {
> m_proxy = proxy;
> }
>
> public void do()
> {
> m_proxy.do();
> }
> }
>
Yes, that was my thought.
> Do keep in mind that there is a heavy penalty for creating
> classes with BCEL due to the class compilation time.
Sure.
> There
> is still a penalty involved with the wrapper class. I'm not
> sure if it is because hotspot is not recompiling or inlining
> it or if there is some other technical issue I am not aware
> of. I will say that BCEL programming is a royal pain. While
> I believe this is what is happening, there could be some
> gotchas that I am not aware of that sap the performance.
>
Thanks for clarifying, Berin!
Carsten
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@excalibur.apache.org
For additional commands, e-mail: dev-help@excalibur.apache.org
Apache Excalibur Project -- URL: http://excalibur.apache.org/
Re: [RT] About proxies and pooling
Posted by Berin Loritsch <bl...@d-haven.org>.
Carsten Ziegeler wrote:
> Berin Loritsch wrote:
>
>>>Hmm, just curious. If we would create BCEL proxies wouldn't
>>>the performance problem go away?
>>
>>There is BCEL proxy generating code in there already (still some
>>minor issues, but decent enough).
>>
>>The BCEL code was significantly faster than reflection based
>>dynamic proxies, but there is still a considerable overhead to
>>BCEL proxies. I can't remember if the price was 5 to 1 or 3 to 1
>>for the BCEL proxies.
>>
>
> Ok, I have not looked at the BCEL code yet, but my thought was that it
> works this way:
> Imagine you have an interface A with one method do(), you create
> a proxy that implements interface A as well, holds a reference to
> the wrapped component and calls inside its own do() method,
> simply the do() method of the wrapped object.
> Is it this way? If so, I wouldn't understand the performance problem :)
This is the rough equivalent of what BCEL generates:
class BCELGeneratedProxy implements A
{
private final A m_proxy;
public BCELGeneratedProxy(A proxy)
{
m_proxy = proxy;
}
public void do()
{
m_proxy.do();
}
}
Do keep in mind that there is a heavy penalty for creating classes with
BCEL due to the class compilation time. There is still a penalty
involved with the wrapper class. I'm not sure if it is because hotspot
is not recompiling or inlining it or if there is some other technical
issue I am not aware of. I will say that BCEL programming is a royal
pain. While I believe this is what is happening, there could be some
gotchas that I am not aware of that sap the performance.
--
"Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe trying to
produce bigger and better idiots. So far, the Universe is winning."
- Rich Cook
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@excalibur.apache.org
For additional commands, e-mail: dev-help@excalibur.apache.org
Apache Excalibur Project -- URL: http://excalibur.apache.org/
RE: [RT] About proxies and pooling
Posted by Carsten Ziegeler <cz...@s-und-n.de>.
Berin Loritsch wrote:
> >
> > Hmm, just curious. If we would create BCEL proxies wouldn't
> > the performance problem go away?
>
> There is BCEL proxy generating code in there already (still some
> minor issues, but decent enough).
>
> The BCEL code was significantly faster than reflection based
> dynamic proxies, but there is still a considerable overhead to
> BCEL proxies. I can't remember if the price was 5 to 1 or 3 to 1
> for the BCEL proxies.
>
Ok, I have not looked at the BCEL code yet, but my thought was that it
works this way:
Imagine you have an interface A with one method do(), you create
a proxy that implements interface A as well, holds a reference to
the wrapped component and calls inside its own do() method,
simply the do() method of the wrapped object.
Is it this way? If so, I wouldn't understand the performance problem :)
Carsten
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@excalibur.apache.org
For additional commands, e-mail: dev-help@excalibur.apache.org
Apache Excalibur Project -- URL: http://excalibur.apache.org/
Re: [RT] About proxies and pooling
Posted by Berin Loritsch <bl...@d-haven.org>.
Carsten Ziegeler wrote:
> Shash Chatterjee wrote:
>
>
>>On a related issue, I have found that the choice betwen
>>java.lang.Proxy proxies and BCEL proxies are important. A
>>lot of people dislike byte-code-modified classes, all though
>>that argument might be deemed bordering somewhere between
>>technical and religious.
>>
>
> Hmm, just curious. If we would create BCEL proxies wouldn't
> the performance problem go away?
There is BCEL proxy generating code in there already (still some
minor issues, but decent enough).
The BCEL code was significantly faster than reflection based
dynamic proxies, but there is still a considerable overhead to
BCEL proxies. I can't remember if the price was 5 to 1 or 3 to 1
for the BCEL proxies.
--
"Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe trying to
produce bigger and better idiots. So far, the Universe is winning."
- Rich Cook
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@excalibur.apache.org
For additional commands, e-mail: dev-help@excalibur.apache.org
Apache Excalibur Project -- URL: http://excalibur.apache.org/
RE: [RT] About proxies and pooling
Posted by Carsten Ziegeler <cz...@s-und-n.de>.
Shash Chatterjee wrote:
>
> Carsten,
>
> > I think we should always create a proxy.
> > WDYT?
> >
>
> A while back I did a performance comparison of Fortress with
> and without proxies (and posted it to the Avalon dev list, I
> believe). Although the component lookup time difference,
> with and without the overhead of proxy creation, wasn't
> significant, the method invocation time with proxies was an
> order of magnitude higher. For applications that only lookup
> the component once, or rarely, but make many method calls on
> the component (possibly iterating in a loop), the overhead
> can quickly add up.
>
Ok.
> I think the safety of not being able to cast a component
> willy-nilly is a great advantage during development. But, a
> choice of whether to have proxies at run-time or not is
> valuable for performance reasons.
>
Ok.
> On a related issue, I have found that the choice betwen
> java.lang.Proxy proxies and BCEL proxies are important. A
> lot of people dislike byte-code-modified classes, all though
> that argument might be deemed bordering somewhere between
> technical and religious.
>
Hmm, just curious. If we would create BCEL proxies wouldn't
the performance problem go away?
Carsten
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@excalibur.apache.org
For additional commands, e-mail: dev-help@excalibur.apache.org
Apache Excalibur Project -- URL: http://excalibur.apache.org/
Re: [RT] About proxies and pooling
Posted by Shash Chatterjee <sh...@badfw.org>.
Carsten,
> I think we should always create a proxy.
> WDYT?
>
A while back I did a performance comparison of Fortress with and without
proxies (and posted it to the Avalon dev list, I believe). Although the
component lookup time difference, with and without the overhead of proxy
creation, wasn't significant, the method invocation time with proxies was an
order of magnitude higher. For applications that only lookup the component
once, or rarely, but make many method calls on the component (possibly
iterating in a loop), the overhead can quickly add up.
I think the safety of not being able to cast a component willy-nilly is a
great advantage during development. But, a choice of whether to have proxies
at run-time or not is valuable for performance reasons.
On a related issue, I have found that the choice betwen java.lang.Proxy
proxies and BCEL proxies are important. A lot of people dislike
byte-code-modified classes, all though that argument might be deemed bordering
somewhere between technical and religious.
Shash
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@excalibur.apache.org
For additional commands, e-mail: dev-help@excalibur.apache.org
Apache Excalibur Project -- URL: http://excalibur.apache.org/
Re: [RT] About proxies and pooling
Posted by Leo Simons <ls...@jicarilla.org>.
Carsten Ziegeler wrote:
> a) Proxy Handling in Fortress
> Currently it's possible to define/configure if/how Fortress
> is creating a proxy for a component. I'm wondering if this
> flexibility is really required.
> I think we should always create a proxy.
flexibility is nice, but comes at the cost of increased code complexity
(with fortress you don't just choose between proxying or not, you choose
between a possible n proxy implementations which need to be consistently
used).
In pico the proxying choice is deferred to the handler (ie the
ComponentHandler in fortress-speak), which means you can use things like
the delegate pattern. It would be nice to set something like that up.
> - Performance
I don't believe proxies could ever increase performance. In your
example, you can create a non-proxy Entry object or Helper (or something
like that), ie like phoenix, which is more perfomant than proxying.
> - Better Support for non thread-safe components. See below.
yes.
> Now, by always creating a proxy we can remove/clean up some code
> in Fortress and it gets a little bit smaller as well :)
>
> WDYT?
before we do that we should get in place a more modern and more
efficient proxy helper (ie CGLIB). Brian McCallister, Leo Sutic, Howard
L. Ship are some of the people I know that have done this.
> b) Pooling (or handling of non thread-safe components)
the big one. I've blogged about this several times. I'll go link-hunting
in the morning. Suffice to say I agree with you and with PeterD (ie the
ReleaseUtil thing is nice; ServiceManager.release() could of course be
used for the same basic idea even if it is perhaps less elegant), yes,
it can be done, yes, it can increase perfomance, and yes, it can be done
safely.
I got halfway through implementing this for pico (using a ReleaseUtil 'n
stuff). Leo Sutic has an in-house setup for this around ServiceManager.
> I conclude from the docs, that e.g. HiveMind is doing it this way.
sort-of.
> WDYT?
yes. I want this.
- LSD
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@excalibur.apache.org
For additional commands, e-mail: dev-help@excalibur.apache.org
Apache Excalibur Project -- URL: http://excalibur.apache.org/