I'm overall +1 with this proposal, with some minor changes described in
comments inline.
Raymond Feng wrote:
Hi,
As we agreed, the conversation id alone is not sufficient to deal with
conversations. We need to maintain the state of the conversations
(STARTED, ENDED or EXPIRED).
Right, if I understand correctly we need to keep the state of a
conversation in a central place in a Tuscany runtime that all
participants can point to, allowing one to end the conversation, and the
other conversation participants to see that it has ended.
I propose that we do the following:
1) Define a ConversationManager like:
public interface ConversationManager() {
String start(String conversationID); // If the conversationID is
null, the system will generate one. Returns the conversation ID
Conversation startConversation(Object conversationID) as the
conversation ID is not always a String.
Change start to startConversation to make clear that it's the
conversation that you're starting and not the ConversationManager.
Also I think it's better to return the Conversation object (see below
for its contents).
void end(String conversationID); // Ends the conversation
void endConversation(Conversation conversation)
Don't you need another method to make a conversation expire?
ConversationState getConversationState(String conversationID); //
Get the state of the conversation
Conversation getConversation(Object conversationID)
void register(ConversationListener listener); // Register a listener
void unregister(ConversationListener listener); // Remove a listener
Let's try to be consistent with other listener interfaces:
addListener(ConversationListener listener)
removeListener(ConversationListener listener)
Also, these methods should be on the Conversation object described below
I think.
}
public interface ConversationListener() {
void conversationStarted(String conversationID);
void conversationEnded(String conversationID);
void conversationExpired(String conversationID);
}
Pass Conversation conversation instead of String conversationID.
If the methods are on the Conversation object instead of the
ConversationManager they can be simpler I think:
public interface ConversationListener() {
void conversationStarted();
void conversationEnded();
void conversationExpired();
}
public enum ConversationState {
STARTED, ENDED, EXPIRED
}
class Conversation {
ConversationState state;
Object conversationID;
}
Having this class allows you to evolve it over time, does not rely on
the fact that conversations are stored in a map, and also IMO better
represents what you'll store in persistent storage in the future.
Do we we need an expiry time field here as well?
2) The proxy or callable references will only keep the conversation
ID. Whenever the Conversation object is referenced or we need to
perform any actions to a conversation, we use the ID to look up the
state of the conversation.
3) Move the expiration timer from the ConversationScopeContainer to
the ConversationManager.
If different Conversations can have different expiration timers then the
timer needs to be on the Conversation object instead of the
ConversationManager.
4) The ConversationScopeContainer will be registered as listener to
the ConversationManager. When an active conversation is started,
expired or ended, the ConversationScopeContainer will be notified.
It might be easier to register the actual instance wrapper wrappering
the component instance associated with a particular conversation.
5) The ConversationManager maintains the conversations using an
in-memory Map as the first step. In the future, it can be extended to
backed by a persistent store.
+1 to use an in-memory map for now.
Thanks,
Raymond
----- Original Message ----- From: "Simon Laws"
<[EMAIL PROTECTED]>
To: <tuscany-dev@ws.apache.org>
Sent: Sunday, September 09, 2007 11:10 AM
Subject: Re: Resetting state of service references at conversation end
Hi Raymond
some comments below...
Simon
On 9/9/07, Raymond Feng <[EMAIL PROTECTED]> wrote:
Hi,
I have been thinking of this problem as well. It's not realistic to
search
for all CallableReferences because it can be dynamically created
too. We
Agreed. You would have to have registered them somewhere first. This
is what
happens in the case of the conversation scope container currently.
probably need to use a listener pattern to have all the Conversation
objects
listen on the events of expiration or end of the conversation and reset
the
state based on the event. Another way is to have a pointer to the
This would rely on having the conversation object register with
something
that is able to broadcast these events. Where would be a sensible
place to
put this event broadcasting function. Do we have an internal eventing
feature? Scope container?
ScopeContainer in the ConversationImpl object and query the state of the
conversation before it's used.
This would still involve updating the scope containers to record the
conversation status against conversation id. But maybe this is an easier
generic change. I.e. instigate a collection at the abstract level that
allows conversationIds to be assoicated with the conversation object
that
created them.
You could just store the conversation state and allow the
conversation to
ask for it as you suggest. Not clear to me what this buys though.
By the current design, the ConversationScopeContainer is per
component to
keep implementation instances by conversation id. So when the same
conversation involves two components, there are two
ConversationScopeContainer instances.
I think this design is sound. The missing link for us it so be able to
access a conversation object given conversationId during callback at the
client end.
Thanks,
Raymond
----- Original Message -----
From: "Simon Laws" <[EMAIL PROTECTED]>
To: "tuscany-dev" <tuscany-dev@ws.apache.org>
Sent: Sunday, September 09, 2007 4:15 AM
Subject: Resetting state of service references at conversation end
> When @ConversationEnd is called on a satefull callback the
conversation
id
> of the client reference is not reset back to null. I have put a
fix in
in
> the case where the scope of the originating component is
CONVERSATION.
> This
> relies on storing the Conversation object in the conversational scope
> container so that when the instance is marked for removal the
conversation
> id can be set to null also.
>
> However to make this approach work for all scopes I have to go and
add
> this
> feature to the other scope containers. Before I do this is there
an > easy
> way
> to get to all of a component instances CallableReferences from the
> JavaImplementationInvoker? If there were I could search for the
> conversation
> object with the matching conversationId rather than adding extra
code > to
> store it away.
>
> Simon
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
--
Jean-Sebastien
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]