See inline.
Simon
Raymond Feng wrote:
Comments inline.
Thanks,
Raymond
----- Original Message ----- From: "Simon Nash" <[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Tuesday, September 11, 2007 7:47 AM
Subject: Re: WS-Addressing mapping (was Re: What is
Message.set/getCallableReference used for?)
Thanks for pointing out this issue. I think we're OK with just
using ConversationID as the correlator as long as we make the
following assumptions:
1. The correlation from ConversationID to callback object is done
on a per-reference basis.
Are you assuming for the lifecylce of a conversation, there is only one
effective callback object for a given service reference?
>
Yes. This seems consistent with the following spec words: "...callback
messages go to the client and are then routed to the specific instance
that has been registered as the callback object". See further comments
below on this.
Even so, we
still need to do some correlations (using the callback endpoint URI as
the key?) to relate a callback to the given service reference, right?
Logically yes, but I don't think any explicit correlation on endpoint
URI is needed. I was expecting each callback endpoint to keep its own
correlation table that maps ConversationID to callback object. (This
is probably just a particular implementation of what you are saying.)
2. The callback goes to the callback object that is set into the
reference at the time the callback is made, not at the time
the forward call is made.
Consider the following code:
myRef = componentContext.getServiceReference(convInterface, refName);
myRef.setCallback(callback1);
myRef.getService().startConversation();
myRef.setCallback(callback2);
myRef.getService().continueConversation();
myRef.setCallback(callback3);
Are you saying if the myRef.setCallback() is called for multiple times,
the effective callback object will override the previous one? If so and
if startConversation() and contineConversation() are one-way async
operations, the result is unpredictable.
Yes, I am saying that. The situation won't arise unless someone changes
the callback object after making an async call. If the callback object
were never set, then all callbacks would go to a single instance of the
client component. It seems reasonable to think of the callback object
as a way of redirecting callbacks from this single instance to a different
single instance on the client side, rather than a way of redirecting
callbacks to multiple client-side instances on a per-call basis.
Another way to look at this is that the callback object instance becomes
part of the state of the conversation. This seems consistent with the
requirement that a callback object that isn't a service reference can
only be used with a stateful callback. If a different unique
correlation ID were used to locate the callback object, there would
be no need for the stateful callback limitation.
With the assumptions listed above, the callbacks from startConversation()
and continueConversation() would go to callback3 (the current value)
instead of callback1 and callback2 respectively (the values at the time
of the forward calls). I don't see anything in the spec that says that
this is not correct.
Assuming both the forward call and callback are synchronous, if the
callback happens in the startConversation() method of the target
service, then it will go to callback1, right? In this case, the
setCallback(callback2) hasn't even been called.
Yes, thanks for the clarification. I realised just as I pushed Send that
I hadn't been clear that I was thinking of the async case where callbacks
arrived after all the code had been executed.
Simon
Does this take care of the cases you had in mind?
Simon
Raymond Feng wrote:
+1 on the proposal. There is one more thing to add.
For the case that the callback object is not a ServiceReference, we
don't flow it in the Message, but we still need to correlate the
callback to this object so that the callback can be routed to the
right callback object. ConversationID alone is good enough, because
we can use different callback objects in the same conversation. I
suggest that we add a "CallbackObjectID" to reference parameter under
the CallbackReference. The CallbackObjectID can be the system hash
code of the callback object. The ConversationID + CallbackObjectID
will be the key for the correlation.
Do you agree?
Thanks,
Raymond
----- Original Message ----- From: "Jean-Sebastien Delfino"
<[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Monday, September 10, 2007 3:43 PM
Subject: Re: WS-Addressing mapping (was Re: What is
Message.set/getCallableReference used for?)
Comments inline.
[snip]
Simon Nash wrote:
I agree that we need a conclusion. I believe the detailed proposal
below
supports all the SCA semantics and I'd like to propose that we go
with it
for Tuscany 1.0.
Any comments, questions, agreement, or disagreement?
Simon
I was initially thinking that the Callback EPR should be a separate
header outside of the To EPR but the code snippet that you put
together to simulate the SCA built-in callback (at the bottom of
that email) convinced me that I was wrong about it :)
So I'm +1 with your proposal in [1]:
Request message
<wsa:To>
<wsa:EndpointReference xmlns:wsa="..." xmlns:tuscany="...">
<wsa:Address>...URI of the service being invoked...</wsa:Address>
<wsa:ReferenceParameters>
<tuscany:CallbackID>callback-A01</tuscany:CallbackID>
<tuscany:ConversationID>conversation-006</tuscany:ConversationID>
<tuscany:CallbackReference>
<wsa:EndpointReference>
<wsa:Address>...URI of the service for the
callback...</wsa:Address>
<wsa:EndpointReference>
</tuscany:CallbackReference>
</wsa:ReferenceParameters>
</wsa:EndpointReference>
</wsa:To>
Callback message:
<wsa:To>
<wsa:EndpointReference xmlns:wsa="..." xmlns:tuscany="...">
<wsa:Address>...URI of the service for the callback...</wsa:Address>
<wsa:ReferenceParameters>
<tuscany:CallbackID>callback-A01</tuscany:CallbackID>
<tuscany:ConversationID>conversation-006</tuscany:ConversationID>
</wsa:ReferenceParameters>
</wsa:EndpointReference>
</wsa:To>
In plain text:
- CallbackID flows as a reference parameter of the "To" EPR
- ConversationID flows as a reference parameter of the "To" EPR
- CallbackReference is a well formed EPR and flows as a reference
parameter of the "To" EPR
I think that we should propose this mapping to the OASIS SCA
Bindings workgroup. Different implementations of SCA should follow
the same mapping if we want them to interoperate over Web Services
for example.
[1] http://www.mail-archive.com/[email protected]/msg22923.html
[snip]
Yes, I'm proposing what I said in [1] with a
<tuscany:CallbackReference>
reference parameter under the wsa:To stateful EPR. Looking at
this again,
it could be slightly improved to eliminate the
<wsa:EndpointReference>
and <wsa:Address> within <tuscany:CallbackReference>, giving:
<wsa:To>
<wsa:EndpointReference xmlns:wsa="..." xmlns:tuscany="...">
<wsa:Address>...URI of the service being
invoked...</wsa:Address>
<wsa:ReferenceParameters>
<tuscany:CallbackID>callback-A01</tuscany:CallbackID>
<tuscany:ConversationID>conversation-006</tuscany:ConversationID>
<tuscany:CallbackReference>
...URI of the service for the callback...
</tuscany:CallbackReference>
</wsa:ReferenceParameters>
</wsa:EndpointReference>
</wsa:To>
This requires the <tuscany:CallbackReference> to be "fluffed up"
into
a <wsa:To><wsa:EndpointReference> when the callback is sent, with
the
<tuscany:CallbackID> and <tuscany:ConversationID> as its reference
parameters:
<wsa:To>
<wsa:EndpointReference xmlns:wsa="..." xmlns:tuscany="...">
<wsa:Address>...URI of the service for the
callback...</wsa:Address>
<wsa:ReferenceParameters>
<tuscany:CallbackID>callback-A01</tuscany:CallbackID>
<tuscany:ConversationID>conversation-006</tuscany:ConversationID>
</wsa:ReferenceParameters>
</wsa:EndpointReference>
</wsa:To>
Simon
I'm not keen on doing that. I'd prefer to stick to your initial
proposal which seems cleaner to me, using the same standard form to
represent the CallbackReference EPR in the request message and the
To EPR in the callback message.
@Service(Client.class)
class Client {
ComponentContext componentContext;
Writer writer;
write(inputData) {
target =
componentContext.getServiceReference(Writer.class, "writer");
self = componentContext.createSelfReference();
id = new UUID();
target.setCallbackID(id);
self.setCallbackID(id);
target.setCallback(self);
target.getService().asyncWrite(target, inputData);
}
written(myReference) {
// data <myReference.getCallbackID()> has been written
}
}
@Service(Writer.class)
class Writer {
@OneWay
asyncWrite(myReference, inputData) {
// actually write the data
clientReference = myReference.getCallback();
clientReference.getService().written(clientReference);
}
}
I'd suggest a small variation of this pseudo-code, to be more in
line with the protocol that you proposed (the callbackID doesn't
flow in the CallbackReference in the request message):
@Service(Client.class)
class Client {
ComponentContext componentContext;
Writer writer;
write(inputData) {
target = componentContext.getServiceReference(Writer.class,
"writer");
self = componentContext.createSelfReference();
id = new UUID();
target.setCallbackID(id);
target.setCallback(self);
target.getService().asyncWrite(target, inputData);
}
written(myReference) {
// data <myReference.getCallbackID()> has been written
}
}
@Service(Writer.class)
class Writer {
@OneWay
asyncWrite(myReference, inputData) {
// actually write the data
clientReference = myReference.getCallback();
clientReference.setCallbackID(myReference.getCallbackID());
clientReference.getService().written(clientReference);
}
}
--
Jean-Sebastien
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]