You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tuscany.apache.org by Raymond Feng <en...@gmail.com> on 2007/09/13 06:42:02 UTC

Optimize the reference injection for java components

Hi,

We use either JDK or CGLib proxies in reference injections for java 
components. It is a bit heavy and unnecessary for some cases. I now add a 
simple optimization to inject the implementation instance directly if the 
following criteria are met:

1) Both the source and target are java components
2) The binding is local SCA binding
3) The target implementation class implements/extends the source 
interface/class
4) The target component scope is either STATELESS or COMPOSITE
5) There is only one invoker (JavaImplementationInvoker) in each invocation 
chain for all the operations

What do you think?

Thanks,
Raymond


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


Re: Optimize the reference injection for java components

Posted by Mike Edwards <mi...@gmail.com>.
Raymond,

Raymond Feng wrote:
> Hi,
> 
> We use either JDK or CGLib proxies in reference injections for java 
> components. It is a bit heavy and unnecessary for some cases. I now add 
> a simple optimization to inject the implementation instance directly if 
> the following criteria are met:
> 
> 1) Both the source and target are java components
> 2) The binding is local SCA binding
> 3) The target implementation class implements/extends the source 
> interface/class
> 4) The target component scope is either STATELESS or COMPOSITE
> 5) There is only one invoker (JavaImplementationInvoker) in each 
> invocation chain for all the operations
> 
> What do you think?
> 
> Thanks,
> Raymond
> 

This kind of optimisation has always been part of the idea behind SCA, 
so in general, I think this is fine.

There are probably a lot of wrinkles (Simon's note mentions some) and I 
suggest that this should be prototyped and checked out before going into 
the mainline code.

Yours,  Mike.

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


Re: Optimize the reference injection for java components

Posted by Mike Edwards <mi...@gmail.com>.
Folks,

Comments inline....

Mike.

Simon Nash wrote:
> By changing the lifecycle of the target instance I mean that it would
> be created eagerly (on source reference creation) rather than lazily
> (on source reference invocation) as is done currently.  From looking
> at the new code I believe this is what would happen.  (If I have
> misunderstood, please correct me.)
> 
> An example of the difference is that if a conversational scoped
> component A references a stateless scoped component B and invokes it
> ten times through the same reference within the same conversation,
> at present we would create ten copies of B, one per invocation.
> With this new code, we would create one copy of B at the time that
> the A instance is created.  This changes the lifecycle of B.  It is
> arguably a change for the better, but it is still a change.

My concern is whether the existing code has some deep-rooted dependence 
on the lifecycle of component instances.  This may well become a problem 
over time.

> 
> Now consider a stateless instance with references to other stateless
> components.  For a long chain of references and services (A -> B -> C
> -> D -> E -> F), all six objects would be created at the same time when
> the A instance is created, rather than just creating the A instance
> and a proxy for B.  Depending on the execution path through A, it's
> possible that five of these six objects will never be used.  This
> doesn't seem good to me.  I'm not surprised that our tests don't pick
> this up, because it isn't easy to test for this kind of thing.
> However, it can cause resource and performance issues in a real-world
> environment because of an excessive number of object creations and
> garbage collection cycles.

This is a good point and it emphasises that optimisation must be looked 
at "in the large".  Object pooling is one technique that is used in 
servers to deal with the problem of excessive creation of objects.  It 
applies even if objects are only created "on demand" since if a new 
object is created for each method invocation, that can mean a huge heap 
of objects too.

I note that the use of proxies actually creates double the number of 
objects - one proxy and one target for each invocation...

> 
> One way to get the best of both worlds could be to inject a proxy
> initially and replace it with a direct instance pointer when the proxy
> is first invoked.  This will need more code than the current proposed
> approach, but I think it may be worth doing for the efficiency
> benefits.  Ideally we would prototype different approaches to see
> which one yields the best tradeoff in terms of overall execution
> efficiency  and resource consumption.  We don't have time to do this
> before the 1.0 release.

I agree with the sentiment that this needs more time.  Optimisation is 
no easy trick.  Unless there is some big performance problem right 
now,it can be safely left for future work.

> 
>   Simon
> 

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


Re: Optimize the reference injection for java components

Posted by Simon Nash <na...@hursley.ibm.com>.
By changing the lifecycle of the target instance I mean that it would
be created eagerly (on source reference creation) rather than lazily
(on source reference invocation) as is done currently.  From looking
at the new code I believe this is what would happen.  (If I have
misunderstood, please correct me.)

An example of the difference is that if a conversational scoped
component A references a stateless scoped component B and invokes it
ten times through the same reference within the same conversation,
at present we would create ten copies of B, one per invocation.
With this new code, we would create one copy of B at the time that
the A instance is created.  This changes the lifecycle of B.  It is
arguably a change for the better, but it is still a change.

Now consider a stateless instance with references to other stateless
components.  For a long chain of references and services (A -> B -> C
-> D -> E -> F), all six objects would be created at the same time when
the A instance is created, rather than just creating the A instance
and a proxy for B.  Depending on the execution path through A, it's
possible that five of these six objects will never be used.  This
doesn't seem good to me.  I'm not surprised that our tests don't pick
this up, because it isn't easy to test for this kind of thing.
However, it can cause resource and performance issues in a real-world
environment because of an excessive number of object creations and
garbage collection cycles.

One way to get the best of both worlds could be to inject a proxy
initially and replace it with a direct instance pointer when the proxy
is first invoked.  This will need more code than the current proposed
approach, but I think it may be worth doing for the efficiency
benefits.  Ideally we would prototype different approaches to see
which one yields the best tradeoff in terms of overall execution
efficiency  and resource consumption.  We don't have time to do this
before the 1.0 release.

   Simon

Raymond Feng wrote:

> Please keep in mind that in my proposal we optimize only if the target 
> scope is stateless or composite. And the injection is happening for each 
> source instance using a object factory that underneath look up the 
> target instance from the scope container. I believe it's safe and it 
> doesn't change the lifecycle of the target instance at all.
> 
> Here is the code I modified in 
> "org.apache.tuscany.sca.implementation.java.invocation.JavaComponentContextProvider.java" 
> and the build is successful.
> 
>    private static class OptimizedObjectFactory<T> implements 
> ObjectFactory<T> {
>        private ScopeContainer scopeContainer;
> 
>        public OptimizedObjectFactory(ScopeContainer scopeContainer) {
>            super();
>            this.scopeContainer = scopeContainer;
>        }
> 
>        public T getInstance() throws ObjectCreationException {
>            try {
>                return (T)scopeContainer.getWrapper(null).getInstance();
>            } catch (TargetResolutionException e) {
>                throw new ObjectCreationException(e);
>            }
>        }
> 
>    }
> 
>    private <B> ObjectFactory<B> createObjectFactory(Class<B> interfaze, 
> RuntimeWire wire) {
>        Binding binding = wire.getSource().getBinding();
>        // Check if it's wireable binding for optimization
>        if (binding instanceof WireableBinding) {
>            WireableBinding wireableBinding = (WireableBinding)binding;
>            Component component = wireableBinding.getTargetComponent();
>            if (component != null) {
>                Implementation implementation = 
> component.getImplementation();
>                // Check if the target component is java component
>                if (implementation instanceof JavaImplementation) {
>                    JavaImplementation javaImplementation = 
> (JavaImplementation)implementation;
>                    if 
> (interfaze.isAssignableFrom(javaImplementation.getJavaClass())) {
>                        ScopedRuntimeComponent scopedComponent = 
> (ScopedRuntimeComponent)component;
>                        ScopeContainer scopeContainer = 
> scopedComponent.getScopeContainer();
>                        Scope scope = scopeContainer.getScope();
>                        if (scope == Scope.COMPOSITE || scope == 
> Scope.STATELESS || scope == Scope.SYSTEM) {
>                            boolean optimizable = true;
>                            for (InvocationChain chain : 
> wire.getInvocationChains()) {
>                                if (chain.getHeadInvoker() != 
> chain.getTailInvoker()) {
>                                    optimizable = false;
>                                    break;
>                                }
>                            }
>                            if (optimizable) {
>                                return new 
> OptimizedObjectFactory<B>(scopeContainer);
>                            }
>                        }
>                    }
>                }
>            }
>        }
>        return new WireObjectFactory<B>(interfaze, wire, proxyFactory);
>    }
> 
> Thanks,
> Raymond
> 
> ----- Original Message ----- From: "Simon Nash" <na...@hursley.ibm.com>
> To: <tu...@ws.apache.org>
> Sent: Thursday, September 13, 2007 1:42 AM
> Subject: Re: Optimize the reference injection for java components
> 
> 
>> If I understand this correctly, it would affect the lifecycle of
>> the target component instance.  So when A has a reference to B,
>> the creation of A currently involves creating and injecting a B proxy
>> but not a B instance.  With this change, I think the creation of A
>> would involve creating a B instance and injecting a reference to this
>> B instance into A.  And if B references C, this would in turn involve
>> creating a C instance and injecting its reference into B (and so on).
>>
>> I think there could be many consequences of this change, some of which
>> may not be desirable.  Creation on first invocation is easy to understand
>> and consistent, and I'd be concerned about changing this.  A related
>> consideration is some of the callback cases that currently don't quite
>> work as I would expect, because injection can only happen when an
>> instance is created.  I think there may be cases where we should be
>> injecting/binding a callback reference when the forward call is
>> received and disptached to an instance that already exists, and I'm
>> working on a use case description for this.
>>
>> I would prefer to defer this change until after 1.0 so that we can
>> discuss it more fully to consider all the implications, and coordinate
>> it with resolving the callback issues if we agree that a change is
>> needed there.
>>
>>   Simon
>>
>> Raymond Feng wrote:
>>
>>> Hi,
>>>
>>> We use either JDK or CGLib proxies in reference injections for java 
>>> components. It is a bit heavy and unnecessary for some cases. I now 
>>> add a simple optimization to inject the implementation instance 
>>> directly if the following criteria are met:
>>>
>>> 1) Both the source and target are java components
>>> 2) The binding is local SCA binding
>>> 3) The target implementation class implements/extends the source 
>>> interface/class
>>> 4) The target component scope is either STATELESS or COMPOSITE
>>> 5) There is only one invoker (JavaImplementationInvoker) in each 
>>> invocation chain for all the operations
>>>
>>> What do you think?
>>>
>>> Thanks,
>>> Raymond
>>>
>>>



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


Re: Optimize the reference injection for java components

Posted by Raymond Feng <en...@gmail.com>.
Please keep in mind that in my proposal we optimize only if the target scope 
is stateless or composite. And the injection is happening for each source 
instance using a object factory that underneath look up the target instance 
from the scope container. I believe it's safe and it doesn't change the 
lifecycle of the target instance at all.

Here is the code I modified in 
"org.apache.tuscany.sca.implementation.java.invocation.JavaComponentContextProvider.java" 
and the build is successful.

    private static class OptimizedObjectFactory<T> implements 
ObjectFactory<T> {
        private ScopeContainer scopeContainer;

        public OptimizedObjectFactory(ScopeContainer scopeContainer) {
            super();
            this.scopeContainer = scopeContainer;
        }

        public T getInstance() throws ObjectCreationException {
            try {
                return (T)scopeContainer.getWrapper(null).getInstance();
            } catch (TargetResolutionException e) {
                throw new ObjectCreationException(e);
            }
        }

    }

    private <B> ObjectFactory<B> createObjectFactory(Class<B> interfaze, 
RuntimeWire wire) {
        Binding binding = wire.getSource().getBinding();
        // Check if it's wireable binding for optimization
        if (binding instanceof WireableBinding) {
            WireableBinding wireableBinding = (WireableBinding)binding;
            Component component = wireableBinding.getTargetComponent();
            if (component != null) {
                Implementation implementation = 
component.getImplementation();
                // Check if the target component is java component
                if (implementation instanceof JavaImplementation) {
                    JavaImplementation javaImplementation = 
(JavaImplementation)implementation;
                    if 
(interfaze.isAssignableFrom(javaImplementation.getJavaClass())) {
                        ScopedRuntimeComponent scopedComponent = 
(ScopedRuntimeComponent)component;
                        ScopeContainer scopeContainer = 
scopedComponent.getScopeContainer();
                        Scope scope = scopeContainer.getScope();
                        if (scope == Scope.COMPOSITE || scope == 
Scope.STATELESS || scope == Scope.SYSTEM) {
                            boolean optimizable = true;
                            for (InvocationChain chain : 
wire.getInvocationChains()) {
                                if (chain.getHeadInvoker() != 
chain.getTailInvoker()) {
                                    optimizable = false;
                                    break;
                                }
                            }
                            if (optimizable) {
                                return new 
OptimizedObjectFactory<B>(scopeContainer);
                            }
                        }
                    }
                }
            }
        }
        return new WireObjectFactory<B>(interfaze, wire, proxyFactory);
    }

Thanks,
Raymond

----- Original Message ----- 
From: "Simon Nash" <na...@hursley.ibm.com>
To: <tu...@ws.apache.org>
Sent: Thursday, September 13, 2007 1:42 AM
Subject: Re: Optimize the reference injection for java components


> If I understand this correctly, it would affect the lifecycle of
> the target component instance.  So when A has a reference to B,
> the creation of A currently involves creating and injecting a B proxy
> but not a B instance.  With this change, I think the creation of A
> would involve creating a B instance and injecting a reference to this
> B instance into A.  And if B references C, this would in turn involve
> creating a C instance and injecting its reference into B (and so on).
>
> I think there could be many consequences of this change, some of which
> may not be desirable.  Creation on first invocation is easy to understand
> and consistent, and I'd be concerned about changing this.  A related
> consideration is some of the callback cases that currently don't quite
> work as I would expect, because injection can only happen when an
> instance is created.  I think there may be cases where we should be
> injecting/binding a callback reference when the forward call is
> received and disptached to an instance that already exists, and I'm
> working on a use case description for this.
>
> I would prefer to defer this change until after 1.0 so that we can
> discuss it more fully to consider all the implications, and coordinate
> it with resolving the callback issues if we agree that a change is
> needed there.
>
>   Simon
>
> Raymond Feng wrote:
>
>> Hi,
>>
>> We use either JDK or CGLib proxies in reference injections for java 
>> components. It is a bit heavy and unnecessary for some cases. I now add a 
>> simple optimization to inject the implementation instance directly if the 
>> following criteria are met:
>>
>> 1) Both the source and target are java components
>> 2) The binding is local SCA binding
>> 3) The target implementation class implements/extends the source 
>> interface/class
>> 4) The target component scope is either STATELESS or COMPOSITE
>> 5) There is only one invoker (JavaImplementationInvoker) in each 
>> invocation chain for all the operations
>>
>> What do you think?
>>
>> Thanks,
>> Raymond
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
>> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>>
>>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
> 


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


Re: Optimize the reference injection for java components

Posted by Simon Nash <na...@hursley.ibm.com>.
I like option A better.  It also has the advantage that others
could create alternative experimental patches and post them
so that the results could be compared.

   Simon

Jean-Sebastien Delfino wrote:

> [snip]
> Simon Nash wrote:
> 
>> Thanks for getting these performance numbers.  They confirm that
>> an optimization for this case is needed.  The question is whether
>> the current patch is the right fix, and also whether now is the
>> right time to apply it.
>>
>> Consider the following case, which could also be a common wiring
>> pattern.  A and B are componments with STATELESS implementation
>> scopes.  A has a reference to a service in B, and B has a
>> reference to a service in A (both normal forward references,
>> not callbacks).
>>
>> When an instance of A is created, with the optimization, the
>> stateless scope container will create a new instance of B.
>> Creating the B instance will create another instance of A, which
>> will create another B instance and so on.... until we run out
>> of stack, heap or both.
> 
> 
> I just tested that scenario:
> - getting a StackOverflow with the optimization patch
> - good news is that everything works fine with our current proxy 
> approach :)
> 
>>
>> This is just one example of a problem with the current code.
>> Sebastien has found a few issues with it as well, as well as
>> areas where we don't have good enough test coverage to pick up
>> all the problems that this change could create.  There's probably
>> no test for my scenario above either.  How many more issues are
>> there as well as those that have come up so far?
>>
>> I think we would be taking too much of a risk if we do this now so
>> close to 1.0.  It's a small change in terms of lines of code but
>> it raises big issues in terms of design.  It needs more time for
>> careful consideration and analysis of all the scenarios.
>>
>>   Simon
> 
> 
> How about these two options?
> 
> [A] A well identified JIRA is created for that patch, and people who 
> want to experiment with performance optimization can apply it.
> 
> (exclusive) or
> 
> [B] The optimization is in the code but disabled by default. People can 
> activate it by setting an experimental system property to true.
> 
> Since we're so close to 1.0 and given the StackOverflow I just got with 
> the patch, I'm leaning towards [A].
> 
> Thoughts?
> 



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


Re: Optimize the reference injection for java components

Posted by Jean-Sebastien Delfino <js...@apache.org>.
[snip]
Simon Nash wrote:
> Thanks for getting these performance numbers.  They confirm that
> an optimization for this case is needed.  The question is whether
> the current patch is the right fix, and also whether now is the
> right time to apply it.
>
> Consider the following case, which could also be a common wiring
> pattern.  A and B are componments with STATELESS implementation
> scopes.  A has a reference to a service in B, and B has a
> reference to a service in A (both normal forward references,
> not callbacks).
>
> When an instance of A is created, with the optimization, the
> stateless scope container will create a new instance of B.
> Creating the B instance will create another instance of A, which
> will create another B instance and so on.... until we run out
> of stack, heap or both.

I just tested that scenario:
- getting a StackOverflow with the optimization patch
- good news is that everything works fine with our current proxy approach :)

>
> This is just one example of a problem with the current code.
> Sebastien has found a few issues with it as well, as well as
> areas where we don't have good enough test coverage to pick up
> all the problems that this change could create.  There's probably
> no test for my scenario above either.  How many more issues are
> there as well as those that have come up so far?
>
> I think we would be taking too much of a risk if we do this now so
> close to 1.0.  It's a small change in terms of lines of code but
> it raises big issues in terms of design.  It needs more time for
> careful consideration and analysis of all the scenarios.
>
>   Simon

How about these two options?

[A] A well identified JIRA is created for that patch, and people who 
want to experiment with performance optimization can apply it.

(exclusive) or

[B] The optimization is in the code but disabled by default. People can 
activate it by setting an experimental system property to true.

Since we're so close to 1.0 and given the StackOverflow I just got with 
the patch, I'm leaning towards [A].

Thoughts?

-- 
Jean-Sebastien


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


Re: Optimize the reference injection for java components

Posted by Simon Nash <na...@hursley.ibm.com>.
Thanks for getting these performance numbers.  They confirm that
an optimization for this case is needed.  The question is whether
the current patch is the right fix, and also whether now is the
right time to apply it.

Consider the following case, which could also be a common wiring
pattern.  A and B are componments with STATELESS implementation
scopes.  A has a reference to a service in B, and B has a
reference to a service in A (both normal forward references,
not callbacks).

When an instance of A is created, with the optimization, the
stateless scope container will create a new instance of B.
Creating the B instance will create another instance of A, which
will create another B instance and so on.... until we run out
of stack, heap or both.

This is just one example of a problem with the current code.
Sebastien has found a few issues with it as well, as well as
areas where we don't have good enough test coverage to pick up
all the problems that this change could create.  There's probably
no test for my scenario above either.  How many more issues are
there as well as those that have come up so far?

I think we would be taking too much of a risk if we do this now so
close to 1.0.  It's a small change in terms of lines of code but
it raises big issues in terms of design.  It needs more time for
careful consideration and analysis of all the scenarios.

   Simon

Jean-Sebastien Delfino wrote:

> Comments at the bottom
> 
> Raymond Feng wrote:
> 
>> Yes, we check the presence of any other inteceptors than the java 
>> implementation invoker in the chain for each operation. We optimize 
>> only if java implementation invoker is the only one.
>>
>> Thanks,
>> Raymond
>>
>> ----- Original Message ----- From: "scabooz" <sc...@gmail.com>
>> To: <tu...@ws.apache.org>
>> Sent: Thursday, September 13, 2007 5:18 PM
>> Subject: Re: Optimize the reference injection for java components
>>
>>
>>> Yes, I agree.  The only risk of doing this for stateless
>>> components is that an improperly coded implementation
>>> could malfunction due to left over state from the previous use.
>>> Getting a clean instance every time will cover up the error.
>>> I'm not trying to dissuade you from doing it, just pointing out
>>> potholes.
>>>
>>> The other question I forgot to ask was about policy.  Does
>>> the invocation handler check you proposed ensure that policy
>>> interceptors will get control between components?
>>>
>>> Dave
>>>
>>> ----- Original Message ----- From: "Raymond Feng" <en...@gmail.com>
>>> To: <tu...@ws.apache.org>
>>> Sent: Thursday, September 13, 2007 5:12 PM
>>> Subject: Re: Optimize the reference injection for java components
>>>
>>>
>>>> Even for the stateless case, I would argue it's legal to do the 
>>>> optimization.
>>>>
>>>> The SCA java spec says:
>>>>
>>>> "283 1.2.4.1. Stateless scope
>>>> 284 For stateless components, there is no implied correlation 
>>>> between service requests."
>>>>
>>>> I think it should also be valid to get the same instances for 
>>>> multiple requests. For JEE stateless sessions, the container usally 
>>>> maintains an instance pool and pick the instance from pool as 
>>>> needed. So there is only one request at a time, then there is a good 
>>>> chance that the same instance is picked.
>>>>
>>>> My understanding of "stateless" is that there is no garauntee that 
>>>> multiple requests will be routed to the same instance.
>>>>
>>>> Thanks,
>>>> Raymond
>>>>
>>>> ----- Original Message ----- From: "scabooz" <sc...@gmail.com>
>>>> To: <tu...@ws.apache.org>
>>>> Sent: Thursday, September 13, 2007 1:57 PM
>>>> Subject: Re: Optimize the reference injection for java components
>>>>
>>>>
>>>>>
>>>>> Comments inline
>>>>>
>>>>> ----- Original Message ----- From: "Mike Edwards" 
>>>>> <mi...@gmail.com>
>>>>> To: <tu...@ws.apache.org>
>>>>> Sent: Thursday, September 13, 2007 11:44 AM
>>>>> Subject: Re: Optimize the reference injection for java components
>>>>>
>>>>>
>>>>>> Simon,
>>>>>>
>>>>>> Some comments inline....
>>>>>>
>>>>>> Simon Nash wrote:
>>>>>>
>>>>>>> If I understand this correctly, it would affect the lifecycle of
>>>>>>> the target component instance.  So when A has a reference to B,
>>>>>>> the creation of A currently involves creating and injecting a B 
>>>>>>> proxy
>>>>>>> but not a B instance.  With this change, I think the creation of A
>>>>>>> would involve creating a B instance and injecting a reference to 
>>>>>>> this
>>>>>>> B instance into A.  And if B references C, this would in turn 
>>>>>>> involve
>>>>>>> creating a C instance and injecting its reference into B (and so 
>>>>>>> on).
>>>>>>>
>>>>>>> I think there could be many consequences of this change, some of 
>>>>>>> which
>>>>>>> may not be desirable.  Creation on first invocation is easy to 
>>>>>>> understand
>>>>>>> and consistent, and I'd be concerned about changing this.
>>>>>>
>>>>>>
>>>>>> But creation can occur at other times.  Scope controls this - 
>>>>>> COMPOSITE scope implies creation at deployment time, for example.  
>>>>>> So you need to be able to deal with these cases anyway.  Creation 
>>>>>> on first invocation sounds like only one possible behaviour that 
>>>>>> must be handled.
>>>>>>
>>>>>
>>>>> Since Raymond has already constrained the scenario to local, 
>>>>> injection of the
>>>>> instance should be ok for REQUEST, CONVERSATION and COMPOSITE
>>>>> because they should all be "singletons" during the life of the 
>>>>> request that is
>>>>> currently in flight.  For STATELESS, you're supposed to get a new 
>>>>> instance
>>>>> on every invocation, so I don't think you'd want the optimization 
>>>>> in this case.
>>>>>
>>>>>>> A related
>>>>>>> consideration is some of the callback cases that currently don't 
>>>>>>> quite
>>>>>>> work as I would expect, because injection can only happen when an
>>>>>>> instance is created.  I think there may be cases where we should be
>>>>>>> injecting/binding a callback reference when the forward call is
>>>>>>> received and disptached to an instance that already exists, and I'm
>>>>>>> working on a use case description for this.
>>>>>>
>>>>>>
>>>>>> With Raymond's proposal, I think that the instances involved in 
>>>>>> the call & callback are well known "in advance" and it should work 
>>>>>> properly. Perhaps I'm wrong - and certainly it isn't the way it 
>>>>>> works today, but it could be made to work that way.
>>>>>>
>>>>>
>>>>> Two stateless callbacks in a row would invoke two different
>>>>> stateless instances.  I think you need the proxy for these callback
>>>>> cases also.
>>>>>
>>>>>>>
>>>>>>> I would prefer to defer this change until after 1.0 so that we can
>>>>>>> discuss it more fully to consider all the implications, and 
>>>>>>> coordinate
>>>>>>> it with resolving the callback issues if we agree that a change is
>>>>>>> needed there.
>>>>>>
>>>>>>
>>>>>> That's a fair point and I tend to agree, since this is an 
>>>>>> optimisation, not some fundamental function.  I suspect it will 
>>>>>> take quite a piece of work to make it run properly in all scenarios.
>>>>>>
>>>>>>>
>>>>>>>   Simon
>>>>>>>
>>>>>>
> 
> I added the following test code to the Calculator sample:
> 
>    public double add(double n1, double n2) {
>        //return addService.add(n1, n2);
> 
>        // Warm up
>        double r = 0;
>        for (int i=0; i < 100; i++) {
>            r = addService.add(n1, n2);
>        }
> 
>        // Perform 1 million calls
>        long n = 1000000;
>        long begin = System.currentTimeMillis();
>        for (int i=0; i < n; i++) {
>            r = addService.add(n1, n2);
>        }
>        long end = System.currentTimeMillis();
>              // Print the results
>        double time = ((double)(end - begin));
>        System.out.println("Calls: " + n);
>        System.out.println("Time: " + (long)time + " msec");
>              return r;
>    }
> 
> This code measures the time to perform 1 million invocations through the 
> CalculatorService/addService reference wired to the AddService component.
> 
> Here are some numbers, running in a single thread, on Sun JRE 1.5_10 - 
> Linux RHEL5 - Thinkpad T60P:
> - without Raymond's patch, 1010 msec for 1 million invocations
> - with Raymond's patch, 20 msec for 1 million invocations
> ==> a 50x performance optimization for a very specific wiring pattern, 
> but a very common one, two Java components with the same scope and no 
> interceptors between them.
> 
> I rebuilt the whole trunk with the patch and didn't get any regression.
> 
> I reviewed the code, the comments in this thread, and the spec 
> description of scopes.
> 
> My assessment is that it is safe to apply the patch, and desirable given 
> the performance improvement of 50x, with minor changes:
> 
> a) Test that the reference or service interface is conversational, and 
> in this case go the slow proxy route, as we need to intercept the 
> invocation to handle the conversation state. The fact that the build 
> didn't break with the patch tells me that we need one more test case for 
> conversations :)
> 
> b) In the new code test that scopeContainer is not null. It's not 
> supposed to be null on a JavaImplementation, but I'm paranoid :)
> 
> c) Scope.SYSTEM is not used, you don't need to test for it.
> 
> d) Testing the scope of the target is not sufficient, also test that the 
> scope of the source component is equals to the scope of the target.
> 
> Hope this helps.
> 




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


Re: Optimize the reference injection for java components

Posted by Jean-Sebastien Delfino <js...@apache.org>.
Comments at the bottom

Raymond Feng wrote:
> Yes, we check the presence of any other inteceptors than the java 
> implementation invoker in the chain for each operation. We optimize 
> only if java implementation invoker is the only one.
>
> Thanks,
> Raymond
>
> ----- Original Message ----- From: "scabooz" <sc...@gmail.com>
> To: <tu...@ws.apache.org>
> Sent: Thursday, September 13, 2007 5:18 PM
> Subject: Re: Optimize the reference injection for java components
>
>
>> Yes, I agree.  The only risk of doing this for stateless
>> components is that an improperly coded implementation
>> could malfunction due to left over state from the previous use.
>> Getting a clean instance every time will cover up the error.
>> I'm not trying to dissuade you from doing it, just pointing out
>> potholes.
>>
>> The other question I forgot to ask was about policy.  Does
>> the invocation handler check you proposed ensure that policy
>> interceptors will get control between components?
>>
>> Dave
>>
>> ----- Original Message ----- From: "Raymond Feng" <en...@gmail.com>
>> To: <tu...@ws.apache.org>
>> Sent: Thursday, September 13, 2007 5:12 PM
>> Subject: Re: Optimize the reference injection for java components
>>
>>
>>> Even for the stateless case, I would argue it's legal to do the 
>>> optimization.
>>>
>>> The SCA java spec says:
>>>
>>> "283 1.2.4.1. Stateless scope
>>> 284 For stateless components, there is no implied correlation 
>>> between service requests."
>>>
>>> I think it should also be valid to get the same instances for 
>>> multiple requests. For JEE stateless sessions, the container usally 
>>> maintains an instance pool and pick the instance from pool as 
>>> needed. So there is only one request at a time, then there is a good 
>>> chance that the same instance is picked.
>>>
>>> My understanding of "stateless" is that there is no garauntee that 
>>> multiple requests will be routed to the same instance.
>>>
>>> Thanks,
>>> Raymond
>>>
>>> ----- Original Message ----- From: "scabooz" <sc...@gmail.com>
>>> To: <tu...@ws.apache.org>
>>> Sent: Thursday, September 13, 2007 1:57 PM
>>> Subject: Re: Optimize the reference injection for java components
>>>
>>>
>>>>
>>>> Comments inline
>>>>
>>>> ----- Original Message ----- From: "Mike Edwards" 
>>>> <mi...@gmail.com>
>>>> To: <tu...@ws.apache.org>
>>>> Sent: Thursday, September 13, 2007 11:44 AM
>>>> Subject: Re: Optimize the reference injection for java components
>>>>
>>>>
>>>>> Simon,
>>>>>
>>>>> Some comments inline....
>>>>>
>>>>> Simon Nash wrote:
>>>>>> If I understand this correctly, it would affect the lifecycle of
>>>>>> the target component instance.  So when A has a reference to B,
>>>>>> the creation of A currently involves creating and injecting a B 
>>>>>> proxy
>>>>>> but not a B instance.  With this change, I think the creation of A
>>>>>> would involve creating a B instance and injecting a reference to 
>>>>>> this
>>>>>> B instance into A.  And if B references C, this would in turn 
>>>>>> involve
>>>>>> creating a C instance and injecting its reference into B (and so 
>>>>>> on).
>>>>>>
>>>>>> I think there could be many consequences of this change, some of 
>>>>>> which
>>>>>> may not be desirable.  Creation on first invocation is easy to 
>>>>>> understand
>>>>>> and consistent, and I'd be concerned about changing this.
>>>>>
>>>>> But creation can occur at other times.  Scope controls this - 
>>>>> COMPOSITE scope implies creation at deployment time, for example.  
>>>>> So you need to be able to deal with these cases anyway.  Creation 
>>>>> on first invocation sounds like only one possible behaviour that 
>>>>> must be handled.
>>>>>
>>>>
>>>> Since Raymond has already constrained the scenario to local, 
>>>> injection of the
>>>> instance should be ok for REQUEST, CONVERSATION and COMPOSITE
>>>> because they should all be "singletons" during the life of the 
>>>> request that is
>>>> currently in flight.  For STATELESS, you're supposed to get a new 
>>>> instance
>>>> on every invocation, so I don't think you'd want the optimization 
>>>> in this case.
>>>>
>>>>>> A related
>>>>>> consideration is some of the callback cases that currently don't 
>>>>>> quite
>>>>>> work as I would expect, because injection can only happen when an
>>>>>> instance is created.  I think there may be cases where we should be
>>>>>> injecting/binding a callback reference when the forward call is
>>>>>> received and disptached to an instance that already exists, and I'm
>>>>>> working on a use case description for this.
>>>>>
>>>>> With Raymond's proposal, I think that the instances involved in 
>>>>> the call & callback are well known "in advance" and it should work 
>>>>> properly. Perhaps I'm wrong - and certainly it isn't the way it 
>>>>> works today, but it could be made to work that way.
>>>>>
>>>>
>>>> Two stateless callbacks in a row would invoke two different
>>>> stateless instances.  I think you need the proxy for these callback
>>>> cases also.
>>>>
>>>>>>
>>>>>> I would prefer to defer this change until after 1.0 so that we can
>>>>>> discuss it more fully to consider all the implications, and 
>>>>>> coordinate
>>>>>> it with resolving the callback issues if we agree that a change is
>>>>>> needed there.
>>>>>
>>>>> That's a fair point and I tend to agree, since this is an 
>>>>> optimisation, not some fundamental function.  I suspect it will 
>>>>> take quite a piece of work to make it run properly in all scenarios.
>>>>>
>>>>>>
>>>>>>   Simon
>>>>>>
>>>>>

I added the following test code to the Calculator sample:

    public double add(double n1, double n2) {
        //return addService.add(n1, n2);

        // Warm up
        double r = 0;
        for (int i=0; i < 100; i++) {
            r = addService.add(n1, n2);
        }

        // Perform 1 million calls
        long n = 1000000;
        long begin = System.currentTimeMillis();
        for (int i=0; i < n; i++) {
            r = addService.add(n1, n2);
        }
        long end = System.currentTimeMillis();
       
        // Print the results
        double time = ((double)(end - begin));
        System.out.println("Calls: " + n);
        System.out.println("Time: " + (long)time + " msec");
       
        return r;
    }

This code measures the time to perform 1 million invocations through the 
CalculatorService/addService reference wired to the AddService component.

Here are some numbers, running in a single thread, on Sun JRE 1.5_10 - 
Linux RHEL5 - Thinkpad T60P:
- without Raymond's patch, 1010 msec for 1 million invocations
- with Raymond's patch, 20 msec for 1 million invocations
==> a 50x performance optimization for a very specific wiring pattern, 
but a very common one, two Java components with the same scope and no 
interceptors between them.

I rebuilt the whole trunk with the patch and didn't get any regression.

I reviewed the code, the comments in this thread, and the spec 
description of scopes.

My assessment is that it is safe to apply the patch, and desirable given 
the performance improvement of 50x, with minor changes:

a) Test that the reference or service interface is conversational, and 
in this case go the slow proxy route, as we need to intercept the 
invocation to handle the conversation state. The fact that the build 
didn't break with the patch tells me that we need one more test case for 
conversations :)

b) In the new code test that scopeContainer is not null. It's not 
supposed to be null on a JavaImplementation, but I'm paranoid :)

c) Scope.SYSTEM is not used, you don't need to test for it.

d) Testing the scope of the target is not sufficient, also test that the 
scope of the source component is equals to the scope of the target.

Hope this helps.

-- 
Jean-Sebastien


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


Re: Optimize the reference injection for java components

Posted by Raymond Feng <en...@gmail.com>.
Yes, we check the presence of any other inteceptors than the java 
implementation invoker in the chain for each operation. We optimize only if 
java implementation invoker is the only one.

Thanks,
Raymond

----- Original Message ----- 
From: "scabooz" <sc...@gmail.com>
To: <tu...@ws.apache.org>
Sent: Thursday, September 13, 2007 5:18 PM
Subject: Re: Optimize the reference injection for java components


> Yes, I agree.  The only risk of doing this for stateless
> components is that an improperly coded implementation
> could malfunction due to left over state from the previous use.
> Getting a clean instance every time will cover up the error.
> I'm not trying to dissuade you from doing it, just pointing out
> potholes.
>
> The other question I forgot to ask was about policy.  Does
> the invocation handler check you proposed ensure that policy
> interceptors will get control between components?
>
> Dave
>
> ----- Original Message ----- 
> From: "Raymond Feng" <en...@gmail.com>
> To: <tu...@ws.apache.org>
> Sent: Thursday, September 13, 2007 5:12 PM
> Subject: Re: Optimize the reference injection for java components
>
>
>> Even for the stateless case, I would argue it's legal to do the 
>> optimization.
>>
>> The SCA java spec says:
>>
>> "283 1.2.4.1. Stateless scope
>> 284 For stateless components, there is no implied correlation between 
>> service requests."
>>
>> I think it should also be valid to get the same instances for multiple 
>> requests. For JEE stateless sessions, the container usally maintains an 
>> instance pool and pick the instance from pool as needed. So there is only 
>> one request at a time, then there is a good chance that the same instance 
>> is picked.
>>
>> My understanding of "stateless" is that there is no garauntee that 
>> multiple requests will be routed to the same instance.
>>
>> Thanks,
>> Raymond
>>
>> ----- Original Message ----- 
>> From: "scabooz" <sc...@gmail.com>
>> To: <tu...@ws.apache.org>
>> Sent: Thursday, September 13, 2007 1:57 PM
>> Subject: Re: Optimize the reference injection for java components
>>
>>
>>>
>>> Comments inline
>>>
>>> ----- Original Message ----- 
>>> From: "Mike Edwards" <mi...@gmail.com>
>>> To: <tu...@ws.apache.org>
>>> Sent: Thursday, September 13, 2007 11:44 AM
>>> Subject: Re: Optimize the reference injection for java components
>>>
>>>
>>>> Simon,
>>>>
>>>> Some comments inline....
>>>>
>>>> Simon Nash wrote:
>>>>> If I understand this correctly, it would affect the lifecycle of
>>>>> the target component instance.  So when A has a reference to B,
>>>>> the creation of A currently involves creating and injecting a B proxy
>>>>> but not a B instance.  With this change, I think the creation of A
>>>>> would involve creating a B instance and injecting a reference to this
>>>>> B instance into A.  And if B references C, this would in turn involve
>>>>> creating a C instance and injecting its reference into B (and so on).
>>>>>
>>>>> I think there could be many consequences of this change, some of which
>>>>> may not be desirable.  Creation on first invocation is easy to 
>>>>> understand
>>>>> and consistent, and I'd be concerned about changing this.
>>>>
>>>> But creation can occur at other times.  Scope controls this - COMPOSITE 
>>>> scope implies creation at deployment time, for example.  So you need to 
>>>> be able to deal with these cases anyway.  Creation on first invocation 
>>>> sounds like only one possible behaviour that must be handled.
>>>>
>>>
>>> Since Raymond has already constrained the scenario to local, injection 
>>> of the
>>> instance should be ok for REQUEST, CONVERSATION and COMPOSITE
>>> because they should all be "singletons" during the life of the request 
>>> that is
>>> currently in flight.  For STATELESS, you're supposed to get a new 
>>> instance
>>> on every invocation, so I don't think you'd want the optimization in 
>>> this case.
>>>
>>>>> A related
>>>>> consideration is some of the callback cases that currently don't quite
>>>>> work as I would expect, because injection can only happen when an
>>>>> instance is created.  I think there may be cases where we should be
>>>>> injecting/binding a callback reference when the forward call is
>>>>> received and disptached to an instance that already exists, and I'm
>>>>> working on a use case description for this.
>>>>
>>>> With Raymond's proposal, I think that the instances involved in the 
>>>> call & callback are well known "in advance" and it should work 
>>>> properly. Perhaps I'm wrong - and certainly it isn't the way it works 
>>>> today, but it could be made to work that way.
>>>>
>>>
>>> Two stateless callbacks in a row would invoke two different
>>> stateless instances.  I think you need the proxy for these callback
>>> cases also.
>>>
>>>>>
>>>>> I would prefer to defer this change until after 1.0 so that we can
>>>>> discuss it more fully to consider all the implications, and coordinate
>>>>> it with resolving the callback issues if we agree that a change is
>>>>> needed there.
>>>>
>>>> That's a fair point and I tend to agree, since this is an optimisation, 
>>>> not some fundamental function.  I suspect it will take quite a piece of 
>>>> work to make it run properly in all scenarios.
>>>>
>>>>>
>>>>>   Simon
>>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
>>>> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
>>> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
>> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
> 


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


Re: Optimize the reference injection for java components

Posted by scabooz <sc...@gmail.com>.
Yes, I agree.  The only risk of doing this for stateless
components is that an improperly coded implementation
could malfunction due to left over state from the previous use.
Getting a clean instance every time will cover up the error.
I'm not trying to dissuade you from doing it, just pointing out
potholes.

The other question I forgot to ask was about policy.  Does
the invocation handler check you proposed ensure that policy
interceptors will get control between components?

Dave

----- Original Message ----- 
From: "Raymond Feng" <en...@gmail.com>
To: <tu...@ws.apache.org>
Sent: Thursday, September 13, 2007 5:12 PM
Subject: Re: Optimize the reference injection for java components


> Even for the stateless case, I would argue it's legal to do the 
> optimization.
>
> The SCA java spec says:
>
> "283 1.2.4.1. Stateless scope
> 284 For stateless components, there is no implied correlation between 
> service requests."
>
> I think it should also be valid to get the same instances for multiple 
> requests. For JEE stateless sessions, the container usally maintains an 
> instance pool and pick the instance from pool as needed. So there is only 
> one request at a time, then there is a good chance that the same instance 
> is picked.
>
> My understanding of "stateless" is that there is no garauntee that 
> multiple requests will be routed to the same instance.
>
> Thanks,
> Raymond
>
> ----- Original Message ----- 
> From: "scabooz" <sc...@gmail.com>
> To: <tu...@ws.apache.org>
> Sent: Thursday, September 13, 2007 1:57 PM
> Subject: Re: Optimize the reference injection for java components
>
>
>>
>> Comments inline
>>
>> ----- Original Message ----- 
>> From: "Mike Edwards" <mi...@gmail.com>
>> To: <tu...@ws.apache.org>
>> Sent: Thursday, September 13, 2007 11:44 AM
>> Subject: Re: Optimize the reference injection for java components
>>
>>
>>> Simon,
>>>
>>> Some comments inline....
>>>
>>> Simon Nash wrote:
>>>> If I understand this correctly, it would affect the lifecycle of
>>>> the target component instance.  So when A has a reference to B,
>>>> the creation of A currently involves creating and injecting a B proxy
>>>> but not a B instance.  With this change, I think the creation of A
>>>> would involve creating a B instance and injecting a reference to this
>>>> B instance into A.  And if B references C, this would in turn involve
>>>> creating a C instance and injecting its reference into B (and so on).
>>>>
>>>> I think there could be many consequences of this change, some of which
>>>> may not be desirable.  Creation on first invocation is easy to 
>>>> understand
>>>> and consistent, and I'd be concerned about changing this.
>>>
>>> But creation can occur at other times.  Scope controls this - COMPOSITE 
>>> scope implies creation at deployment time, for example.  So you need to 
>>> be able to deal with these cases anyway.  Creation on first invocation 
>>> sounds like only one possible behaviour that must be handled.
>>>
>>
>> Since Raymond has already constrained the scenario to local, injection of 
>> the
>> instance should be ok for REQUEST, CONVERSATION and COMPOSITE
>> because they should all be "singletons" during the life of the request 
>> that is
>> currently in flight.  For STATELESS, you're supposed to get a new 
>> instance
>> on every invocation, so I don't think you'd want the optimization in this 
>> case.
>>
>>>> A related
>>>> consideration is some of the callback cases that currently don't quite
>>>> work as I would expect, because injection can only happen when an
>>>> instance is created.  I think there may be cases where we should be
>>>> injecting/binding a callback reference when the forward call is
>>>> received and disptached to an instance that already exists, and I'm
>>>> working on a use case description for this.
>>>
>>> With Raymond's proposal, I think that the instances involved in the call 
>>> & callback are well known "in advance" and it should work properly. 
>>> Perhaps I'm wrong - and certainly it isn't the way it works today, but 
>>> it could be made to work that way.
>>>
>>
>> Two stateless callbacks in a row would invoke two different
>> stateless instances.  I think you need the proxy for these callback
>> cases also.
>>
>>>>
>>>> I would prefer to defer this change until after 1.0 so that we can
>>>> discuss it more fully to consider all the implications, and coordinate
>>>> it with resolving the callback issues if we agree that a change is
>>>> needed there.
>>>
>>> That's a fair point and I tend to agree, since this is an optimisation, 
>>> not some fundamental function.  I suspect it will take quite a piece of 
>>> work to make it run properly in all scenarios.
>>>
>>>>
>>>>   Simon
>>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
>>> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
>> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
> 


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


Re: Optimize the reference injection for java components

Posted by Mike Edwards <mi...@gmail.com>.
Folks,

Comments inline...

Raymond Feng wrote:
> Even for the stateless case, I would argue it's legal to do the 
> optimization.
> 
> The SCA java spec says:
> 
> "283 1.2.4.1. Stateless scope
> 284 For stateless components, there is no implied correlation between 
> service requests."
> 

You've picked the right spec lines....

> I think it should also be valid to get the same instances for multiple 
> requests. For JEE stateless sessions, the container usally maintains an 
> instance pool and pick the instance from pool as needed. So there is 
> only one request at a time, then there is a good chance that the same 
> instance is picked.

Yes, there is no guarantee that you will get a DIFFERENT instance each 
time.  The only point that is emphasised is that the implementer cannot 
rely on getting the SAME instance for each subsequent request.  If the 
implementer stores some state then that state could be over the hills & 
far away when the next request arrives.

> 
> My understanding of "stateless" is that there is no garauntee that 
> multiple requests will be routed to the same instance.

+1, absolutely

> 
> Thanks,
> Raymond
> 

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


Re: Optimize the reference injection for java components

Posted by Raymond Feng <en...@gmail.com>.
Even for the stateless case, I would argue it's legal to do the 
optimization.

The SCA java spec says:

"283 1.2.4.1. Stateless scope
284 For stateless components, there is no implied correlation between 
service requests."

I think it should also be valid to get the same instances for multiple 
requests. For JEE stateless sessions, the container usally maintains an 
instance pool and pick the instance from pool as needed. So there is only 
one request at a time, then there is a good chance that the same instance is 
picked.

My understanding of "stateless" is that there is no garauntee that multiple 
requests will be routed to the same instance.

Thanks,
Raymond

----- Original Message ----- 
From: "scabooz" <sc...@gmail.com>
To: <tu...@ws.apache.org>
Sent: Thursday, September 13, 2007 1:57 PM
Subject: Re: Optimize the reference injection for java components


>
> Comments inline
>
> ----- Original Message ----- 
> From: "Mike Edwards" <mi...@gmail.com>
> To: <tu...@ws.apache.org>
> Sent: Thursday, September 13, 2007 11:44 AM
> Subject: Re: Optimize the reference injection for java components
>
>
>> Simon,
>>
>> Some comments inline....
>>
>> Simon Nash wrote:
>>> If I understand this correctly, it would affect the lifecycle of
>>> the target component instance.  So when A has a reference to B,
>>> the creation of A currently involves creating and injecting a B proxy
>>> but not a B instance.  With this change, I think the creation of A
>>> would involve creating a B instance and injecting a reference to this
>>> B instance into A.  And if B references C, this would in turn involve
>>> creating a C instance and injecting its reference into B (and so on).
>>>
>>> I think there could be many consequences of this change, some of which
>>> may not be desirable.  Creation on first invocation is easy to 
>>> understand
>>> and consistent, and I'd be concerned about changing this.
>>
>> But creation can occur at other times.  Scope controls this - COMPOSITE 
>> scope implies creation at deployment time, for example.  So you need to 
>> be able to deal with these cases anyway.  Creation on first invocation 
>> sounds like only one possible behaviour that must be handled.
>>
>
> Since Raymond has already constrained the scenario to local, injection of 
> the
> instance should be ok for REQUEST, CONVERSATION and COMPOSITE
> because they should all be "singletons" during the life of the request 
> that is
> currently in flight.  For STATELESS, you're supposed to get a new instance
> on every invocation, so I don't think you'd want the optimization in this 
> case.
>
>>> A related
>>> consideration is some of the callback cases that currently don't quite
>>> work as I would expect, because injection can only happen when an
>>> instance is created.  I think there may be cases where we should be
>>> injecting/binding a callback reference when the forward call is
>>> received and disptached to an instance that already exists, and I'm
>>> working on a use case description for this.
>>
>> With Raymond's proposal, I think that the instances involved in the call 
>> & callback are well known "in advance" and it should work properly. 
>> Perhaps I'm wrong - and certainly it isn't the way it works today, but it 
>> could be made to work that way.
>>
>
> Two stateless callbacks in a row would invoke two different
> stateless instances.  I think you need the proxy for these callback
> cases also.
>
>>>
>>> I would prefer to defer this change until after 1.0 so that we can
>>> discuss it more fully to consider all the implications, and coordinate
>>> it with resolving the callback issues if we agree that a change is
>>> needed there.
>>
>> That's a fair point and I tend to agree, since this is an optimisation, 
>> not some fundamental function.  I suspect it will take quite a piece of 
>> work to make it run properly in all scenarios.
>>
>>>
>>>   Simon
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
>> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
> 


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


Re: Optimize the reference injection for java components

Posted by scabooz <sc...@gmail.com>.
Comments inline

----- Original Message ----- 
From: "Mike Edwards" <mi...@gmail.com>
To: <tu...@ws.apache.org>
Sent: Thursday, September 13, 2007 11:44 AM
Subject: Re: Optimize the reference injection for java components


> Simon,
>
> Some comments inline....
>
> Simon Nash wrote:
>> If I understand this correctly, it would affect the lifecycle of
>> the target component instance.  So when A has a reference to B,
>> the creation of A currently involves creating and injecting a B proxy
>> but not a B instance.  With this change, I think the creation of A
>> would involve creating a B instance and injecting a reference to this
>> B instance into A.  And if B references C, this would in turn involve
>> creating a C instance and injecting its reference into B (and so on).
>>
>> I think there could be many consequences of this change, some of which
>> may not be desirable.  Creation on first invocation is easy to understand
>> and consistent, and I'd be concerned about changing this.
>
> But creation can occur at other times.  Scope controls this - COMPOSITE 
> scope implies creation at deployment time, for example.  So you need to be 
> able to deal with these cases anyway.  Creation on first invocation sounds 
> like only one possible behaviour that must be handled.
>

Since Raymond has already constrained the scenario to local, injection of 
the
instance should be ok for REQUEST, CONVERSATION and COMPOSITE
because they should all be "singletons" during the life of the request that 
is
currently in flight.  For STATELESS, you're supposed to get a new instance
on every invocation, so I don't think you'd want the optimization in this 
case.

>> A related
>> consideration is some of the callback cases that currently don't quite
>> work as I would expect, because injection can only happen when an
>> instance is created.  I think there may be cases where we should be
>> injecting/binding a callback reference when the forward call is
>> received and disptached to an instance that already exists, and I'm
>> working on a use case description for this.
>
> With Raymond's proposal, I think that the instances involved in the call & 
> callback are well known "in advance" and it should work properly. Perhaps 
> I'm wrong - and certainly it isn't the way it works today, but it could be 
> made to work that way.
>

Two stateless callbacks in a row would invoke two different
stateless instances.  I think you need the proxy for these callback
cases also.

>>
>> I would prefer to defer this change until after 1.0 so that we can
>> discuss it more fully to consider all the implications, and coordinate
>> it with resolving the callback issues if we agree that a change is
>> needed there.
>
> That's a fair point and I tend to agree, since this is an optimisation, 
> not some fundamental function.  I suspect it will take quite a piece of 
> work to make it run properly in all scenarios.
>
>>
>>   Simon
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
> 


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


Re: Optimize the reference injection for java components

Posted by Mike Edwards <mi...@gmail.com>.
Simon,

Some comments inline....

Simon Nash wrote:
> If I understand this correctly, it would affect the lifecycle of
> the target component instance.  So when A has a reference to B,
> the creation of A currently involves creating and injecting a B proxy
> but not a B instance.  With this change, I think the creation of A
> would involve creating a B instance and injecting a reference to this
> B instance into A.  And if B references C, this would in turn involve
> creating a C instance and injecting its reference into B (and so on).
> 
> I think there could be many consequences of this change, some of which
> may not be desirable.  Creation on first invocation is easy to understand
> and consistent, and I'd be concerned about changing this.  

But creation can occur at other times.  Scope controls this - COMPOSITE 
scope implies creation at deployment time, for example.  So you need to 
be able to deal with these cases anyway.  Creation on first invocation 
sounds like only one possible behaviour that must be handled.

> A related
> consideration is some of the callback cases that currently don't quite
> work as I would expect, because injection can only happen when an
> instance is created.  I think there may be cases where we should be
> injecting/binding a callback reference when the forward call is
> received and disptached to an instance that already exists, and I'm
> working on a use case description for this.

With Raymond's proposal, I think that the instances involved in the call 
& callback are well known "in advance" and it should work properly. 
Perhaps I'm wrong - and certainly it isn't the way it works today, but 
it could be made to work that way.

> 
> I would prefer to defer this change until after 1.0 so that we can
> discuss it more fully to consider all the implications, and coordinate
> it with resolving the callback issues if we agree that a change is
> needed there.

That's a fair point and I tend to agree, since this is an optimisation, 
not some fundamental function.  I suspect it will take quite a piece of 
work to make it run properly in all scenarios.

> 
>   Simon
> 

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


Re: Optimize the reference injection for java components

Posted by Simon Nash <na...@hursley.ibm.com>.
If I understand this correctly, it would affect the lifecycle of
the target component instance.  So when A has a reference to B,
the creation of A currently involves creating and injecting a B proxy
but not a B instance.  With this change, I think the creation of A
would involve creating a B instance and injecting a reference to this
B instance into A.  And if B references C, this would in turn involve
creating a C instance and injecting its reference into B (and so on).

I think there could be many consequences of this change, some of which
may not be desirable.  Creation on first invocation is easy to understand
and consistent, and I'd be concerned about changing this.  A related
consideration is some of the callback cases that currently don't quite
work as I would expect, because injection can only happen when an
instance is created.  I think there may be cases where we should be
injecting/binding a callback reference when the forward call is
received and disptached to an instance that already exists, and I'm
working on a use case description for this.

I would prefer to defer this change until after 1.0 so that we can
discuss it more fully to consider all the implications, and coordinate
it with resolving the callback issues if we agree that a change is
needed there.

   Simon

Raymond Feng wrote:

> Hi,
> 
> We use either JDK or CGLib proxies in reference injections for java 
> components. It is a bit heavy and unnecessary for some cases. I now add 
> a simple optimization to inject the implementation instance directly if 
> the following criteria are met:
> 
> 1) Both the source and target are java components
> 2) The binding is local SCA binding
> 3) The target implementation class implements/extends the source 
> interface/class
> 4) The target component scope is either STATELESS or COMPOSITE
> 5) There is only one invoker (JavaImplementationInvoker) in each 
> invocation chain for all the operations
> 
> What do you think?
> 
> Thanks,
> Raymond
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
> 
> 



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