OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

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


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.
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).
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.
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.
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.

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.

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









[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]