Hi, Simon.

Thank you for the clarification. There are no recent changes and my understanding was out of sync with the current Tuscany code.

One question for my knowledge: When the injection of @Callback happens, do we get the 'target' from the incoming invocation context or from the components that have references with a matching callback interface wired to the component with the @Callback fields or setters?

Thanks,
Raymond

--------------------------------------------------
From: "Simon Nash" <[email protected]>
Sent: Monday, February 09, 2009 4:10 PM
To: <[email protected]>
Subject: Re: Callback problem with COMPOSITE scoped implementation

Raymond Feng wrote:
Yes, the injected proxy for callback decides its target based on the incoming invocation on the thread. For the concurrent access to the composite-scoped component, synchronizations may be required for the business logic but the callback proxy should be able to handle different clients.
I might have missed some discussion here (apologies if so), but
I don't think an injected callback proxy should be able to handle
more than one client.  This may work in simple cases, but it
doesn't work if the proxy is saved for later use after the
immediate method invocation has returned.  The context won't be
available at that time, so a hard-wired proxy is needed.

In OASIS we have banned callback injection into composite-scoped
components because of the problems with this scenario.  The correct
way to handle this is to call RequestContext.getCallback() on
each invocation of a composite-scoped component, which returns a
a proxy that points to the right (hard-wired) callback target for
the current invocation.

Tuscany callback proxies used to do context-dependent callback
target resolution, but I changed this over a year ago so that the
target is resolved (hard-wired) at the time the proxy is injected.
Has this changed again in recent months?

  Simon

Thanks,
Raymond *From:* Simon Laws <mailto:[email protected]>
*Sent:* Friday, February 06, 2009 8:58 AM
*To:* [email protected] <mailto:[email protected]>
*Subject:* Re: Callback problem with COMPOSITE scoped implementation



On Fri, Feb 6, 2009 at 4:37 PM, Raymond Feng <[email protected] <mailto:[email protected]>> wrote:

    The usage of @Callback in Vamsi's case should be supported too by
    the spec. It's probably a Tuscany bug that has a staled cache based
    on the HelloworldXComponent. Vamsi, do you have a test case that we
    can try?
     Thanks,
    Raymond *From:* Simon Laws <mailto:[email protected]>
    *Sent:* Friday, February 06, 2009 6:33 AM
    *To:* [email protected] <mailto:[email protected]>
    *Subject:* Re: Callback problem with COMPOSITE scoped implementation



    On Fri, Feb 6, 2009 at 2:26 PM, Vamsavardhana Reddy
    <[email protected] <mailto:[email protected]>> wrote:



        On Fri, Feb 6, 2009 at 5:07 PM, Simon Laws
        <[email protected] <mailto:[email protected]>>
        wrote:



            On Thu, Feb 5, 2009 at 1:04 AM, Raymond Feng
            <[email protected] <mailto:[email protected]>> wrote:

                Hi,
                 I realized that I misunderstood the problem after
                reading your case again (where the system hash id for
                the objects are shown).  Sorry for the confusion.
                 1) Tuscany's composite scope management seems to be
                correct.
                 1. HelloworldDelegateComponent is using instance A of
                HelloworldDelegateImpl
                2. HelloworldDelegateComponent2 is using instance B of
                HelloworldDelegateImpl
                3. HelloworldXComponent is using instance C of
                HelloworldImpl.
                2) Tuscany resolves the target for a callback based on
                the SCA context for the incoming invocation. That's why
it works if the scope for HelloworldXComponent is STATELESS.
                 3) When HelloworldXComponent is composite scoped, there
                is one instance. Tuscany runtime probably has some cache
                that keep the resolved callback. And it becomes staled
                when the 2nd call is coming from a different component.
                We'll need to look into the code to fix that.
                 Vamsi, can you attach your test case to a JIRA?
                 Thanks,
                Raymond

                *From:* Raymond Feng <mailto:[email protected]>
                *Sent:* Wednesday, February 04, 2009 1:03 PM
                *To:* [email protected]
                <mailto:[email protected]>
                *Subject:* Re: Callback problem with COMPOSITE scoped
                implementation

                Sorry, I took the wrong class name. But the story stays.
                 In this case is that the "salutation" property is
                injected. It is configured to two different values by
                the two components. Since Tuscany interprets the spec in
                the 1st way, and there is a single java object
                (sample.HelloworldDelegateImpl) , the field got injected
                twice and the later one overrode the first one. That's
                why you only see the same salutation.
                 Thanks,
Raymond *From:* Vamsavardhana Reddy <mailto:[email protected]>
                *Sent:* Wednesday, February 04, 2009 12:47 PM
                *To:* [email protected]
                <mailto:[email protected]>
                *Subject:* Re: Callback problem with COMPOSITE scoped
                implementation

                Raymond,

                HelloworldDelegateComponent and
                HelloworldDelegateComponent2 are using the
                implementation class sample.HelloworldDelegateImpl. Both
                these components are invoking a service from
                HelloworldXComponent which uses implementation class
                sample.HelloworldImpl.  Each of these components are
                using a single instance per component of the respective
                implementation classes through out the scope of the
                composite. Let us say
                1. HelloworldDelegateComponent is using instance A of
                HelloworldDelegateImpl
                2. HelloworldDelegateComponent2 is using instance B of
                HelloworldDelegateImpl
                3. HelloworldXComponent is using instance C of
                HelloworldImpl.

                The problem is that
                a) when A is invoking service from C, C.callback should
                be injected with the callback service provided by A and
                b) when B is invoking service from C, C.callback should
                be injected with the callback service provided by B

                Even though it is one instance of HelloworldImpl that is
                used, the callback field should keep changing depending
                on who is invoking the service.  Don't know if it is
                feasible.

                On Thu, Feb 5, 2009 at 12:49 AM, Raymond Feng
                <[email protected] <mailto:[email protected]>> wrote:

                    Hi,

                    This is interesting. In your case, you have two
                    components HelloworldDelegateComponent and
                    HelloworldDelegateComponent2 that use the same java
                    implementation class: sample.HelloworldImpl which is
                    composite scoped. Now the question is how to
interpret the following statement in the SCA java spec:

                    295 1.2.4.3. Composite scope
                    296 All service requests are dispatched to the same
                    implementation instance for the lifetime of the
                    containing
                    297 composite. The lifetime of the containing
                    composite is defined as the time it becomes active
                    in the runtime
                    298 to the time it is deactivated, either normally
                    or abnormally.

                    There are two ways:

                    1) There is going to be one instance of
                    sample.HelloworldImpl (A) that are shared by
                    HelloworldDelegateComponent and
                    HelloworldDelegateComponent2. Requests to both
                    components will be dispatched to A.

                    2) There are going to be two instances of
                    sample.HelloworldImpl (A & B), one for
                    HelloworldDelegateComponent and the other for
                    HelloworldDelegateComponent2. Request to
                    HelloworldDelegateComponent will be dispatched to  A
                    while requests to HelloworldDelegateComponent2 will
                    be dispatched B.

                    It seems that Tuscany works in the 1st way. We need
                    clarifications from the spec group.

                    Thanks,
                    Raymond

                    From: Vamsavardhana Reddy
                    Sent: Wednesday, February 04, 2009 8:30 AM
                    To: [email protected]
                    <mailto:[email protected]>
                    Subject: Callback problem with COMPOSITE scoped
                    implementation



I have a composite with three components as given below:

                    <composite xmlns="http://www.osoa.org/xmlns/sca/1.0";
                             targetNamespace="http://sample";
                             name="HelloworldDelegate">

                      <component name="HelloworldXComponent">
                          <implementation.java
                    class="sample.HelloworldImpl"/>
                      </component>

                      <component name="HelloworldDelegateComponent">
                          <implementation.java
                    class="sample.HelloworldDelegateImpl"/>
                          <service name="HelloworldDelegate">
                              <binding.ws <http://binding.ws>

uri="http://localhost:8080/tuscany/HelloworldDelegate"/>
                          </service>
                          <reference name="helloworld"
                    target="HelloworldXComponent"/>
                          <property name="salutation">Monsieur</property>
                      </component>

                      <component name="HelloworldDelegateComponent2">
                          <implementation.java
                    class="sample.HelloworldDelegateImpl"/>
                          <service name="HelloworldDelegate">
                              <binding.ws <http://binding.ws>

uri="http://localhost:8080/tuscany/HelloworldDelegate2"/>
                          </service>
                          <reference name="helloworld"
                    target="HelloworldXComponent"/>
                          <property name="salutation">Mr.</property>
                      </component>
                    </composite>

                    HelloworldImpl provides a Helloworld service and
                    requires a HelloworldCallback callback service.
                    HelloworldDelegateImpl provides HelloworldDelegate
                    service and HelloworldCallback service. There are
                    two components, namely HelloworldDelegateComponent
                    (with salutation "Monsieur") and
                    HelloworldDelegateComponent2 (with salutation
                    "Mr.").  Both these components invoke Helloworld
                    service provided by HelloworldXComponent.
                    Both the implementations are COMPOSITE scoped.

                    When I use the HelloworldDelegate service from
                    HelloworldDelegateComponent the output I see in the
                    console is the following:
                      HelloworldDelegateComponent:

HelloworldDelegateImpl(sample.helloworlddelegatei...@28e2f1).sayHello:
                    vamsi
                      HelloworldXComponent:

HelloworldImpl(sample.helloworldi...@10076aa).sayHello:
                    vamsi
                      HelloworldDelegateComponent:

HelloworldDelegateImpl(sample.helloworlddelegatei...@28e2f1).whoIs:
                    vamsi

                    and the message got back is "Hello Monsieur vamsi".
                    ------------------------------
                    When I use the HelloworldDelegate service from
                    HelloworldDelegateComponent the output I see in the
                    console is the following:
                      HelloworldDelegateComponent2:

HelloworldDelegateImpl(sample.helloworlddelegatei...@146e74b).sayHello:
                    vamsi
                      HelloworldXComponent:

HelloworldImpl(sample.helloworldi...@10076aa).sayHello:
                    vamsi
                      HelloworldDelegateComponent:

HelloworldDelegateImpl(sample.helloworlddelegatei...@28e2f1).whoIs:
                    vamsi

                    and the message got back is "Hello Monsieur vamsi".
                     I was expecting "Hello Mr. vamsi".

                    Notice that in the second case, the callback service
                    is called from HelloworldDelegateComponent instead
                    of HelloworldDelegateComponent2. Is this the
                    expected behaviour?
                    -----------------

                    If I make HelloworldImpl as STATELESS scoped (which
                    is the default), then I am seeing that the callback
                    service is invoked on the same component that is
                    invoking the Helloworld service. The following is
                    the output:

                    HelloworldDelegateComponent:

HelloworldDelegateImpl(sample.helloworlddelegatei...@1c704a7).sayHello:
                    vamsi
                    HelloworldXComponent:

HelloworldImpl(sample.helloworldi...@1af0f92).sayHello:
                    vamsi
                    HelloworldDelegateComponent:

HelloworldDelegateImpl(sample.helloworlddelegatei...@1c704a7).whoIs:
                    vamsi
                    Hello Monsieur vamsi

                    HelloworldDelegateComponent2:

HelloworldDelegateImpl(sample.helloworlddelegatei...@61dec0).sayHello:
                    vamsi
                    HelloworldXComponent:

HelloworldImpl(sample.helloworldi...@4f3d72).sayHello:
                    vamsi
                    HelloworldDelegateComponent2:

HelloworldDelegateImpl(sample.helloworlddelegatei...@61dec0).whoIs:
                    vamsi
                    Hello Mr. vamsi

                    What am I missing?

                    ++Vamsi




-- Vamsi


            Isn't it just that the the @Callback is injected once when
            the COMPOSITE scoped component is created that is causing
            the caching of the callback and hence the problem in this
            scenario.

            What happens if you use RequestContext.getCallback()?

        With RequestContext.getCallback(), it is working as expected.
         Simon




-- Vamsi


    Hi Vamsi

    So what you mean by "working as expected." is that the callback goes
    to the client that originates each call as opposed to the first
    client that is injected when you use the inject callback?

    If yes this underlines the fact that Tuscany has the right
    information and is able to create the right proxy. It's just not
    able to inject it into a component whose scope extends over more
    than one call.

    Simon


Hi Raymond

Let me check I understand what you're saying here. If I have a component defined as follows

@Scope("COMPOSITE")
class MyComponentImpl implements MyComponent {

    protected MyCallback myCallback;

    @Callback
    public setMyCallback (MyCallback myCallback) {
        this.myCallback = myCallback;
    }

    void doSomething(){
       myCallback.doTheCallback();
    }
}

with multiple concurrent threads passing through doSomething() your proposition is that the injected myCallback is fixed under the covers to point to the target indicated on each incoming message?

Simon


Reply via email to