I was wondering if there is a simpler way of ending a cached conversation - Quiesce the conversation (Stop using it), then after some period of time, end it.
I create a conversation, cache it in RLY_Conversations, and use it for 50 seconds. After 1 minute, the dialog timer servicing proc ends the conversation. There will be no messages sent around the time the End Conversation takes place, thus no race conditions.
Do you see any problems with this method?
Select @.DialogHandle = [conversation_handle]
From RLY_Conversations
Where TableName = @.TableName and IsActive = 1 And
CreatedTmstp > dateadd(ss, -50, getdate())
if @.DialogHandle is null
Begin
-- initialize a conversation and record it in our reuse table
BEGIN DIALOG CONVERSATION @.DialogHandle
FROM SERVICE FirstHostRelayService
TO SERVICE 'SecondHostRelayService'
ON CONTRACT RelayContractSentByAny
WITH ENCRYPTION=OFF ;
-- cache the dialog handle to minimize dialog creation overhead.
Insert into RLY_Conversations (
TableName, conversation_handle, conversation_id, is_initiator, service_contract_id,
conversation_group_id, service_id, lifetime, state, state_desc, IsActive, CreatedBy, CreatedTmstp
)
Select @.TableName, conversation_handle, conversation_id, is_initiator, service_contract_id,
conversation_group_id, service_id, lifetime, state, state_desc, 1, 'Setup', getdate()
From sys.conversation_endpoints
Where conversation_handle = @.DialogHandle;
-- initiate housekeeping process
BEGIN CONVERSATION TIMER ( @.DialogHandle )
TIMEOUT = 60;
End
Hi Bill,
Thanks for reading my blog!
I'm not sure I follow the question, but if I understand correctly you begin a dialog, use it for 50 seconds and then end it, based on th timer, 10 seconds later. If that is correct, I would recommend against it.
For once, if the target never sends any message you should not end the dialog from the sender's side first, as per http://blogs.msdn.com/remusrusanu/archive/2006/04/06/570578.aspx. I can't stress the importance of this, I am faced every day with people reporting some problem that could had been avoided by not using this fire-and-forget pattern.
Second, altohugh I'm not familiar with your application, I think you are running on some very tight budgets of time when relying on the application to finish it's work in 50 seconds and allowing only a 10 seconds margin for the timer to pop and quiesce the dialog. The SEND operations could be delayed by a lock, the application logic might be delayed a bit, the database might hit a log growth or a datafile growth, there might be a temporary resource constraint (memory, execution threads etc). Anything that delayes the 50 seconds SEND time might cause a race between a SEND and the timer trying to quiesce operation. Is just my opinion that in the persisted, transacted database operations world anything measured in seconds will eventually run into problems in production, even more so when talking about asynchronous operations like messaging. How about starting the 60 seconds timer after every SEND? Using BEGIN CONVERSATION TIMER again when a timer is active has the effect of resting the timer to the new value (there is only one timer per dialog). This way the timer would be continously updated and if no SEND occurs for 60 seconds, the timer will pop.
HTH,
~ Remus
No comments:
Post a Comment