sca-j message
[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
--
[Date Index]
| [Thread Index]
| [List Home]
Subject: Re: [sca-j] ISSUE 25: Detailed proposal for non-conversational callbacks
- From: Simon Nash <NASH@uk.ibm.com>
- To: sca-j@lists.oasis-open.org
- Date: Wed, 13 Aug 2008 16:33:24 +0100
Meeraj,
Thanks for these comments and questions.
My responses are inline as <scn>....</scn>.
Simon
Simon C. Nash, IBM Distinguished Engineer
Member of the IBM Academy of Technology
Tel. +44-1962-815156 Fax +44-1962-818999
"Meeraj Kunnumpurath"
<mkunnumpurath@googlemail.com>
12/08/2008 16:38
|
To
| Simon Nash/UK/IBM@IBMGB
|
cc
| sca-j@lists.oasis-open.org
|
Subject
| Re: [sca-j] ISSUE 25: Detailed proposal
for non-conversational callbacks |
|
Simon,
Sure, I thought I had replied to the TC list, anyway I have copied.
Thanks
Meeraj
On Tue, Aug 12, 2008 at 10:09 AM, Simon Nash <NASH@uk.ibm.com>
wrote:
Meeraj,
These are good comments and questions and I'm sure other TC members will
be interested in the discussion. Are you OK if I copy the sca-j list
on my response?
Simon
Simon C. Nash, IBM Distinguished Engineer
Member of the IBM Academy of Technology
Tel. +44-1962-815156 Fax +44-1962-818999
"Meeraj Kunnumpurath"
<mkunnumpurath@googlemail.com>
11/08/2008 23:30
|
To
| Simon Nash/UK/IBM@IBMGB
|
cc
|
|
Subject
| Re: [sca-j] ISSUE 25: Detailed proposal
for non-conversational callbacks |
|
Simon,
I have a few questions/comments on the proposal, both from a user's and
implementor's perspectives, if you could kindly clarify.
1. From the title of the note I assume, the proposal is for callbacks to
composite and stateless components, both synchronous and otherwise.
<scn>Yes.</scn>
2. Correlation is important on asynchronous callbacks,
as multiple callbacks can come out of order, where as with synchronous
callbacks, clients don't need any additional information for correlation
as one forward call would result in one or more synchronous callbacks (may
be not for composite scope components).
<scn>I don't think this is correct. There
could be multiple synchronous callbacks in progress on different threads,
with each of them issuing callbacks. If a callback needs to be correlated
to a forward call, it needs to carry the identity of that forward call,
as there could be multiple forward calls in progress at the same time.</scn>
3. With stateless components, both synchronous and asynchronous
callbacks are going to come to a different instance than the component
that actually made the forward invocation. So, any instance information
(like the callable reference), wouldn't be of any use for correlating the
callback to the forward call.
<scn>Callable references can be compared for equality.
They can also be sent across business interfaces (with their identity
preserved). So any stateful component in the domain could perform
this correlation, using the original callable reference (sent to it by
the stateless instance that made the forward call) and the callback's callable
reference (sent to it by the stateless instance that received the callback).</scn>
4. For composite components, unless we use some smart
proxy on the callable reference, there is a potential threading issue in
using any instance information for correlating callbacks. Also, any business
state stored as instance variables on composite components would be inherently
thread unsafe.
<scn>I'm not quite sure I understand the point you
are making here. The threading issues that we have with the current
APIs are resolved by this proposal, as all callable references are immutable.
To transmit a request with a different identity, a new callable reference
must be created. There is no operation to set a new identity into
a callable reference, which would cause threading problems as you describe.
For correlation information such as a table of pending requests and
immutable identifiers for them, there are many Java techniques for handling
such data in a thread-safe way.</scn>
5. In my opinion, the semantics of correlating forward and callback invocations
belong to the user domain and should be achieved using user data, rather
than using the API.
<scn>It could be done that way. My earlier
proposal (see http://www.oasis-open.org/apps/org/workgroup/sca-j/email/archives/200803/msg00064.html)
did exactly that. However, my current proposal has the advantage
that each client of a service can choose whether or not it needs per-call
correlation, without affecting the service's interface or implementation.
This provides a clean separation between what the service needs and
what the client needs, thus reducing client/service coupling. The
other approach of adding user data for correlation purposes means that
if a service chooses to support correlation, every client of that service
must always pass the correlation data, even if it doesn't require correlation.
(See Mike E's recent email on this topic.)</scn>
As a general point, may I express my genuine concern (which I have already
expressed in a previous thread) of bleeding technology API (like CallableReference)
into the user code. As a user, I would always want the technology to be
non-invasive, and being able to provide whatever infrastructure it provides
to be transparent to the user code.
<scn>This proposal keeps that to an absolute minimum.
We already have APIs for a client to use a CallableReference object
to make an invocation and for a service to obtain a CallableReference object
representing its invocation. This proposal is a small extension of
those existing APIs. It also allows the current APIs that manipulate
callback IDs to be removed, while providing equivalent functionality. Overall
I believe it's a simplification of what is currently in the API.</scn>
Kind regards
Meeraj
On Thu, Aug 7, 2008 at 11:43 PM, Simon Nash <NASH@uk.ibm.com>
wrote:
Here is a proposed semantic model for callbacks that is independent of
implementation type or binding type.
Insert the following text after line 2455 in the SCA Assembly spec, CD01
rev1.
A call from a client component to a service that is defined using a bidirectional
interface element (a bidirectional service) conceptually carries
the following information in additional to its business data. The
actual form of the information that is passed from client to service depends
on the binding that is used for the wire connecting the reference and the
service.
The information passed is as follows:
1. A callback address that the service can use to make callback invocations
on the client. This MUST either be a physical address such as a network-addressable
endpoint to which callback invocations are made, or a logical identifier
that can be used by the client to identify a callback that it is expected
to process (for example, if the client obtains callbacks by polling). This
address MUST be present on every service invocation, and MUST be generated
by the client.
2. An invocation identifier that the client can use to correlate callback
invocations with service invocations that it has made previously. This
identifier MAY be present on a service invocation, as decided by the client.
If it is present, it MUST be generated by the client. If a
bidirectional service receives an invocation containing this identifier,
the service MUST attach the same invocation identifier to all callbacks
that are semantically associated with that service invocation, as determined
by the service's business logic. SCA runtimes MUST support client-side
comparison of invocation identifiers for equality or inequality with other
invocation identifiers.
The generation of a callback address is determined by the binding in use,
and is described in the relevant binding specification. The generation
and comparison of invocation identifiers by a client is determined by the
client's language implementation, and is described in the relevant implementation
specification. The association of callback invocations to service
invocations is determined by the service's language implementation, and
is described in the relevant implementation specification.
- - - - - - - - - - - - - - - - -
Here is a proposed Java language binding for the above semantic model.
For a Java client of a bidrectional service, the invocation identifier
is determined by the CallableReference object that was used for the invocation.
This is the CallableReference object that would be obtained by invoking
the ComponentContext.cast() API on the type-safe proxy through which the
invocation was made. If a client wishes to attach a different invocation
identifier to a subsequent invocation, it does this by calling the CallableReference.createCallableReference()
API to create a new CallableReference object, and using this CallableReference
object to make the subsequent invocation. The CallableReference object
returned by createCallableReference() MUST have an invocation identifier
that differs from the invocation identifiers of the original CallableReference
object and all other CallableReference objects created from that object
by invoking its createCallableReference() method.
The following example code snippet illustrates the simple case where the
same invocation identifier is passed on every invocation:
@Remotable
@Callback(OrderConfirm.class)
public interface FruitStore {
void orderFruit(String type, int quantity);
}
@Remotable
public interface OrderConfirm {
void confirmOrder(boolean accepted);
}
@Reference
private FruitStore store;
private int confirmed;
public void placeOrder() {
store.orderFruit("apples", 12); // passes the invocation
identifier for the CallableReference object associated with the "store"
proxy
store.orderFruit("apples", 24); // passes the same
invocation identifier
}
public void confirmOrder(int available) {
confirmed += available;
}
The following example code snippet illustrates the ability to pass a different
invocation identifier on every invocation for correlation purposes:
@Reference
private CallableReference<FruitStore> store;
private CallableReference<FruitStore> appleOrder;
private CallableReference<FruitStore> plumOrder;
private int confirmedApples;
private int confirmedPlums;
public void placeOrders() {
appleOrder = store.createCallableReference(); // creates
a new CallableReference object with its own invocation identifier
appleOrder.getService().orderFruit("apples", 12); //
passes the invocation identifier for appleOrder
appleOrder.getService().orderFruit("apples", 24); //
passes the same invocation identifier
plumOrder = store.createCallableReference(); // creates a
new CallableReference object with its own invocation identifier
plumOrder.getService().orderFruit("plums", 12); //
passes the invocation identifier for plumOrder
}
@Context
ComponentContext context;
public void confirmOrder(int available) {
CallableReference<FruitStore> ref = context.getRequestContext().getServiceReference();
if ref.equals(appleOrder) {
confirmedApples += available;
} else if ref.equals(plumOrder) {
confirmedPlums += available;
} else {
// should not happen
}
}
For a Java bidirectional service, the invocation identifier for a callback
made by that service is determined by the CallableReference object that
was used for the callback invocation. This is the CallableReference
object that would be obtained by invoking the ComponentContext.cast() API
on the type-safe proxy through which the callback invocation was made.
When the SCA runtime injects a proxy or a CallableReference object
for a callback, or returns a CallableReference object from the RequestContext.getServiceReference()
API, the CallableReference object MUST be associated with the invocation
identifier from the service call, and the SCA runtime MUST use this invocation
identifier for all callback invocations made though any proxy for which
the ComponentContext.cast() API would return this CallableReference object.
The following example code snippet illustrates the use of an injected proxy
to obtain the callback reference. This coding style is useful for
stateless-scoped service implementations.
@Callback
OrderConfirm confirm; // captures the invocation identifier passed
on this call
public void orderFruit(String fruit, int quantity) {
confirm.confirmOrder(quantity); // passes back the invocation
identifier
}
The following example code snippet illustrates the use of the RequestContext
object to obtain the callback reference. This coding style is useful
for composite-scoped or conversation-scoped service implementations.
@Context
ComponentContext context;
public void orderFruit(String fruit, int quantity) {
CallableReference<FruitStore> ref = context.getRequestContext().getServiceReference();
// captures the invocation identifier passed on this call
OrderConfirm cbRef = ref.getCallback();
cbRef.confirmOrder(quantity); // passes back the invocation
identifier
}
- - - - - - - - - - - - - - - - -
The above proposed Java API also requires the following spec changes or
clarifications to the JavaCAA spec:
1. Object identity round-tripping and state sharing for ComponentContext.cast()
<--> CallableReference.getService(). This would become the
resolution for JAVA-10.
2. Addition of a getCallback() method to CallableReference.
3. Changing the semantics of RequestContext.getServiceReference() when
called within a callback method, so that this API returns a CallableReference
object for the service method that made the callback invocation.
Simon
Simon C. Nash, IBM Distinguished Engineer
Member of the IBM Academy of Technology
Tel. +44-1962-815156 Fax +44-1962-818999
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number
741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6
3AU
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number
741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6
3AU
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number
741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6
3AU
[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
--
[Date Index]
| [Thread Index]
| [List Home]