[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]
Subject: ISSUE 8: Concurrency model for Service Reference instances
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. 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 {
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 {
if (storeRef.getConversation() == null)
storeRef.setConversationID(chooseID());
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]