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