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: Revised proposal for non-conversational callbacks


Hi Simon,

Thanks for writing this up. I'm going to comment specifically on the  
issues highlighted by Case 2 so I will trim the original email and  
respond inline...

Jim

On Sep 29, 2008, at 7:33 AM, Simon Nash wrote:

<snip/>

>
> ======
> CASE 2
> ======
>
> @Remotable
> @Callback(OrderConfirm.class)
> public interface FruitStore {
>    void orderFruit(Order order);
> }
>
> @Remotable
> public interface OrderConfirm {
>    void confirmOrder(OrderResponse response);
> }
>
> @XmlRootElement     // assuming JAXB
> public class Order implements Serializable {
>    public Order() {
>        // ...
>    }
>
>    public Order(String type, int qty) {
>        // ...
>    }
>
>    String getType() {
>        // ...
>    }
>
>    void setType(String type) {
>        // ...
>    }
>
>    int getQuantity() {
>        // ...
>    }
>
>    void setQuantity(int qty) {
>        // ...
>    }
> }
>
> @XmlRootElement     // assuming JAXB
> public class OrderResponse implements Serializable {
>    public OrderResponse() {
>        // ...
>    }
>    public OrderResponse(int available) {
>        // ...
>    }
>
>    int getAvailable() {
>        // ...
>    }
>
>    void setAvailable(int qty) {
>        // ...
>    }
> }
>
> The client could be implemented as follows.  As an exercise to the
> reader, what is the scope of the client implementation?  I'll leave
> you to consider this for a while, and return to this topic below.
>
> public class MyClient implements OrderConfirm {
>
>    @Context
>    RequestContext context;
>
>    @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();
>        Order myOrder = new Order("apples", 12);
>        appleOrder.getService().orderFruit(myOrder);
>        myOrder = new Order("apples", 24);
>        appleOrder.getService().orderFruit(myOrder);
>        plumOrder = store.createCallableReference();
>        myOrder = new Order("plums", 12);
>        plumOrder.getService().orderFruit(myOrder);
>    }
>
>    public void confirmOrder(OrderResponse response) {
>        CallableReference<FruitStore> ref =  
> context.getServiceReference();
>        if ref.equals(appleOrder) {
>            confirmedApples += response.getAvailable();
>        } else if ref.equals(plumOrder) {
>            confirmedPlums += response.getAvailable();
>        } else {
>            // should not happen
>        }
>    }
> }
>
<snip section showing the service provider since it doesn't impact  
what I am going to say/>
>
> Now to return to our earlier unanswered question, what is the scope of
> the client implementation?
>
This was the issue highlighted by Meeraj on one of the  
calls...Basically, it can't be any scope, i.e. using member variables  
for request-level correlation won't work. I'll try and explain why  
below.

> It can't be STATELESS, because the callback would get a new instance
> with a new set of instance variables and the correlation wouldn't  
> work.
>
> It can't be COMPOSITE, because this requires a single instance of the
> client component.  Typically there could be many clients active
> simultaneously, each placing a separate order.
>
> It can't be REQUEST, because REQUEST scope only lasts across local
> invocations, and the FruitStore and OrderConfirm interfaces are
> remotable.
>
> It's awkward to make it CONVERSATION, because this would require us to
> introduce a conversational interface.  The provider controls the
> definition of the FruitStore and OrderConfirm interfaces, so the  
> client
> can't make either of those conversational.  The client could make the
> interface by which it's invoked conversational, but this seems wrong
> because this scenario doesn't require statefulness between the client
> and its invoker, only between the client and its callbacks.
>
It can't be conversation scope either since a conversation-scoped  
instance may be called on multiple threads and storing request- 
specific information in member variables is not thread-safe.

> A possible solution would be to introduce a new scope (e.g., STATEFUL
> or CALLBACK), which causes callbacks to be routed to the same stateful
> instance that initiated the forward call.  When an invocation on a
> STATEFUL scoped instance returns, the instance would be released.   
> This
> solves the problem for synchronous callbacks (as in this example) but
> not if the callbacks are asynchronous.  The only way to handle the
> possibility of asynchronous callbacks seems to be to use case 1 and
> design this into the provider interface.
>
I'm not sure a callback scope is practical or desirable. It would mean  
compartmentalizing an instance until a callback has run to completion.  
By "compartmentalizing" an instance, I mean blocking access to it from  
any other thread, either for forward calls or other callbacks:

A-->B-->C
          <--

If B is the component to be called back, invocations must not be  
dispatched from A until B has been called back.

> I'd appreciate comments on any of this, especially on the final  
> twist of
> the plot.  Are there any other solutions to the case 2 scope problem?
> If not, is it worth adding the mechanisms to support case 2 if this  
> can
> only handle synchronous callbacks?
>
I'm also not sure synchronous callbacks will work either. For example,

A---->B--->C
	    <---

If A-->B is one-way, two invocations could be made through B  
simultaneously. Even if B-->C is synchronous, two callbacks may  
therefore be dispatched to B simultaneously.

I think the root issue is that the client implementation attempts to  
perform request-level correlation via member variables, which can  
never work unless the runtime compartmentalizes an instance. Request  
level correlation really needs to be done "on the stack." That is, via  
application or "business" level constructs that are part of service  
operation parameter data.

I do believe, however, conversational callbacks are very important but  
I won't open that can of worms quite yet so we can focus on request- 
level callback correlation.

Jim

>  Simon
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this mail list, you must leave the OASIS TC that
> generates this mail.  Follow this link to all your TCs in OASIS at:
> https://www.oasis-open.org/apps/org/workgroup/portal/my_workgroups.php



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