[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]