← Prev in month ← Prev in thread

Another early morning brainstorm - conversations revisited

From
Simon Nash <>
Date
2008-07-18T12:46:03+00:00
ID
Thread
Another early morning brainstorm - conversations revisited
In Wednesday's discussion at the F2F,
Anish made the point that using the proposed CallableReference model to
handle conversations has the problem that it requires the client to create
the "conversation ID", but this responsibility should be with
the server.  Anish was also concerned that combining the "callback
ID" and "conversation ID" concepts changes the callback
programming model depending whether or not a conversation is in progress.

A simple extension to the model already
proposed can solve both these problems.  A conversation would be initiated
by the service creating a CallableReference and returning it to the client.
 This CallableReference contains an identity for the conversation.
 This client then makes multiple calls through this CallableReference
instance.  Because these calls all carry the same identity, a conversation-scoped
service will dispatch all of them to the same instance.

This combination of having the service
initiate a conversation and the client decide when to end it provides the
correct combination of semantics and resolves Anish's first concern..

To resolve Anish's second concern, a
bit more programming or an extra mechanism is needed.  If the client
is using a conversational CallableReference that was created by the service,
it can't add its own correlation ID to this CallableReference because CallableReferences
are immutable.  If it needs this per-call correlation, it would need
to create a new CallableReference and pass this on the call.  One
way to do this would be to use business data.  The client code would
look like this:

CallableReference<OrderService>
myConversation = myService.startNewOrder(); // returns an ID for the entire
fruit order

CallableReference<OrderService>
myAppleOrder = myConversation.createCallableReference(); // create an ID
for the apple order request

myConversation.orderApples(12, myAppleOrder);
// the infrastructure sends an ID for myConversation

CallableReference<OrderService>
myPlumOrder = myConversation.createCallableReference(); // create an ID
for the plum order request

myConversation.orderPlums(6, myPlumOrder);
// the infrastructure sends an ID for myConversation

The service interface looks like this:

public interface OrderService {

    public void orderApples(int
quantity, CallableReference<OrderService>);

    public void orderPlums(int
quantity, CallableReference<OrderService>);

}

The service provider code looks like
this:

public void orderApples(int quantity,
CallableReference<OrderService> myClient) {

    boolean success = placeOrder("apples",
quantity);

    myClient.getCallback().reportResult(success);

}

This works, but it makes the business
interface rather cumbersome, and the business interface and service provider
programming model are different from the non-conversational case.  If
we want to optimize the business interface for this case further, and make
the service provider programming model the same for the conversational
and non-conversational cases, we could allow CallableReferences to be linked
together so that the CallableReference for the callback delegates its forward
call identity to a second CallableReference for the forward call.  Using
this approach, the client code would look like this:

CallableReference<OrderService>
myConversation = myService.startNewOrder(); // returns an ID for the entire
fruit order

CallableReference<OrderService>
myAppleOrder = myConversation.createCallbackReference(); // myAppleOrder
is linked to myConversation

myAppleOrder.orderApples(12); // the
infrastructure sends IDs for both myConversation and myAppleOrder

CallableReference<OrderService>
myPlumOrder = myConversation.createCallbackReference(); // myPlumOrder
is linked to myConversation

myPlumOrder.orderPlums(6); // the infrastructure
sends IDs for both myConversation and myPlumOrder

The service interface now looks like
this:

public interface OrderService {

    public void orderApples(int
quantity);

    public void orderPlums(int
quantity);

}

The service provider code is now identical
to the non-conversational case and looks like this: 

@Context

RequestContext requestContext;

public void orderApples(int quantity)
{

    boolean success = placeOrder("apples",
quantity);

    requestContext.getCallback().reportResult(success);

}

    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
← Prev in month ← Prev in thread