[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]
Subject: AW: ISSUE 8: Concurrency model for Service Reference instances
Hi Michael,
Let me first make sure I understand your scenario. The composite-scoped component is essentially a middle man, involved in 2 conversations, with amazon on one side, and the customer on the other. And the problem is to make sure that requests coming in from the client conversation get passed to the correct amazon conversation. Both conversations can be long running. Does that fit?
I think the scenario we had in mind was much more oriented to short lived conversations. That is, the case where the whole conversation with StoreRef takes place within a single call to buy books. In this case, you simply have to replace the injected field "storeRef" with an injected ComponentContext, and the implementation of buyBook would call context.getService("storeRef"). Whether the component calls storeRef.setConversationID or not, you never have any race conditions.
The situation is more complex for these long-running conversations, and I think it's unsurprising that the code would be, too. In this case, the code would need to map from the client conversation ID, to the ID of the amazon conversation. That is, instead of checking if storeRef.getConversation() is null, the code would call something like lookupStoreRefId(context.getRequestContext().getServiceReference().getConversationID()). If the value returned was non-null, the component it would set the storeRef.conversationID accordingly. Otherwise, it sets the conversionID to chooseID(). The method lookupStoreRefId probably would use a DB, but could use an in memory map, or anything else.
Von: Michael Rowley [mailto:mrowley@bea.com] Gesendet: Donnerstag, 21. Februar 2008 20:45 An: OASIS Java; Barack, Ron Betreff: 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]