sca-j message
[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
--
[Date Index]
| [Thread Index]
| [List Home]
Subject: ISSUE 25: Detailed proposal for non-conversational callbacks
- From: Simon Nash <NASH@uk.ibm.com>
- To: sca-j@lists.oasis-open.org
- Date: Thu, 7 Aug 2008 23:43:21 +0100
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
[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
--
[Date Index]
| [Thread Index]
| [List Home]