[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]
Subject: RE: [sca-j] ISSUE 8: Concurrency model for Service Reference instances
We don't have any concurrency annotation, since I think that Java's synchronization mechanisms should be usable as they are. I also agree with you that the @ReferenceAccessMode might cause the programming model to be overly complicated. I'm also not sure it solves the BookBatch example. Michael -----Original Message----- From: Shih-Chang Chen [mailto:shih-chang.chen@oracle.com] Sent: Friday, February 22, 2008 10:08 AM To: Michael Rowley Cc: OASIS Java; Barack, Ron Subject: Re: [sca-j] ISSUE 8: Concurrency model for Service Reference instances In the sca-j spec-draft I am reading, I did not see an annotation or metadata to control the access modes, concurrent or singleThread, of the component instance (not sure if I use the right term). Did I miss it? The discussion of access modes should be related to this topic (ISSUE 8: Concurrency model for Service Reference instances). In addition to the access modes of the component, each reference could have it's access modes as well. Two possible access mode of a ref I can think of are 'shared/concurent' and 'threadLocal'. Example: @ComponentAccessMode(Concurrent) class AComponent { @ReferenceAccessMode(Shared) @Reference ItemInfoService srv; @ReferenceAccessMode(ThreadLocal) @Reference ItemCheckerService srv; But I think that would make the programming model pretty complicate if you also bring in the discussion of stateless/stateful/conversational. Thanks, -chen Michael Rowley wrote: > > > Here is the description of the issue 8 problem (from the PPT on today's > call): > > > > While the current text says that a service reference represents a single > conversation, it is not clear how a multi-threaded client should protect > a non-conversational service reference's configuration (conversation id, > callback, etc) so that it stays unmodified by other threads until an > actual invocation is executed. > > Consider the following code snippet for example: > > class AComponent { > @Reference ItemCheckerService srv; > > void goCheckItem(long ticket, String itemId) { > ServiceReference sr = (ServiceReference) srv; > sr.setConversationID(ticket); > srv.check(itemId); > } > } > > A simple synchronization may lead to strict serialization of remote > calls which is generally undesirable. > > > > I think we should have a good idea of the likely scenarios in which this > multi-threading will happen. On today's call, Simon suggested that code > could start its own threads. I agree this is true, but I don't want to > concentrate on that case, since I think people who go there are willing > to be pretty sophisticated about the threading logic. > > > > I believe other cases are that the client could be conversation or > composite scoped. Stateless and request scoped components are only > active for one thread at a time. This is implied by the semantics of > the @Init and @Destroy methods, which are called at the beginning and > end of the scope lifetime. For a stateless scope, that lifetime is one > call. For request scope, it is one remotable call (to be clarified > based on one of our open issues). > > > > The scenario where a conversation-scoped client could be active in two > threads at once is possible, but unlikely, so I'll concentrate on the > case where the client is composite scoped. > > > > Consider this scenario: a composite scoped component exists for the > purpose of batching up book orders to Amazon. When orders come in to > the BookBatch component, it forwards them on to Amazon, using the > shopping cart that is associated with the current conversation. After a > certain amount of time, or a certain number of books, the current batch > is purchased, and the conversation is ended. When the next book order > comes in, a new batch (conversation) will be started. How might this look: > > > > @Scope("COMPOSITE") > > class BookBatch { > @Reference BookStore store; > > void buyBook(String ISBN) { > store.addToCart(ISBN); > > if (isTimeToCheckOut()) > > checkOut(); > > } > > > > boolean isTimeToCheckOut() {} > > void checkOut() {} > } > > > > This seems like a potentially common scenario where the client would be > multi-threaded. Now, to run into the problem, we have to imagine that > the client wanted to choose its own conversation ID. So, perhaps it > would look like this: > > > > @Scope("COMPOSITE") > > class BookBatch { > @Reference ServiceReference<BookStore> storeRef; > > void buyBook(String ISBN) { > > if (storeRef.getConversation() == null) > > storeRef.setConversationID(chooseID()); > > > storeRef.getService().addToCart(ISBN); > > > > if (isTimeToCheckOut()) > > checkOut(); > > } > > > > boolean isTimeToCheckOut() {} > > void checkOut() {} > > String chooseID() {} // Choose a conversation ID for the next bookstore > conversation. > } > > > > In this version, we pick a new conversation ID if a conversation isn't > already going and set it on the service reference. > > > > This version has a race condition! Multiple threads could have null > returned from getConversation() and so multiple threads will attempt to > choose the next conversation ID. In this particular case, it probably > doesn't matter which one wins that race, but I suppose that in some > cases it would matter. > > > > Is this the problem we are trying to solve? If so, I'm not sure how the > proposal in the PPT presentation given today would help much. > > > > Ron or Simon, would you be willing to modify this class so that it works > correctly given the proposed resolution to issue 8? > > > > Michael > > >
[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]