Thursday, March 29, 2012

EndDialog

I have a SB program that sends a message and there is an activation procedure on my queue. The activation procedure takes the message from the queue, does some processing with the data, and ends the conversation. (I may, in the future, consider reusing the dialogs.) What I am wondering about is that I never come across the

'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog' message type name that indicates that the dialog has ended. Any ideas why?

From your description it sounds like the activated procedure issues the END CONVERSATION verb after processing the first message. After the END CONVERSATION verb was issued on a handle, you will not receive any other message on that conversation (including EndDialog sent by the peer). If we wouldn't ensure that application would have to keep around the state related to that conversation for an undetermined time.

HTH,

~ Remus

P.S. Thanks for writing those SSB articles

|||

Thanks Remus, that definetly makes sense. Because I won't see that EndDialog message type, what is the best way to go about cleaning the conversation up once I am finished? What I have ran into so far is that when I used END CONVERSATION WITH CLEANUP, the conversation remains in sys.conversation_endpoints with a status of 'Conversing', but if I omit 'WITH CLEANUP', the dialog will close as expected. I would like a way to cleanup that message so that it is removed from the catalog view. Does that make sense?

Thanks again,

Tim

|||

Never ever use END CONVERSATION ... WITH CLEANUP. It is realy a last resort statement itended for administrators. Using it in applications can result in very serious problems.

You must decide who ends the conversation first, depending on the business semantics of the conversation. The party that ends the conversation first is the first one that can say 'I am no longer interested in this conversation, even if this last (EndDialog) message never makes it to my peer'. Some common patterns are:

Notification

1) Initiator begins conversation

2) Initiator sends the notification message

3) Target receives the message

4) Target ends the conversations

5) Initiator receives EndDialog message

6) Initiator ends the conversation

Request-Response (when target does not care is response is lost)

1) Initiator begins conversation

2) Initiator sends the request message

3) Target receives the message

4) Target sends response

5) Target ends the conversations

6) Intiator receives the response

7) Initiator receives EndDialog message

8) Initiator ends the conversation

Request-Response (when target does care is response is lost)

1) Initiator begins conversation

2) Initiator sends the request message

3) Target receives the message

4) Target sends response

5) Intiator receives the response

6) Initiator ends the conversation

7) target receives EndDialog message

8) target ends the conversation

One way stream of messages

1) Initiator begins conversation

2) Initiator sends the one message

2') Initiator sends the one message ...

3) Target receives message(s)

... conversation continues for while with initiator sending messages

4) Initiator decides to intrerupt the stream and sends a special application message (EndOfStream)

5) Target receives the EndOfSream message

6) Target ends the conversations

7) Initiator receives EndDialog message

8) Initiator ends the conversation

One pattern that is actually incorrect is fire-and-forget: initiator begins a conversation, then sends one or more messages, then ends the conversation. This way the initiator never gets any feedback if the messages we actually sent or not. I have a blog entry on this subject: http://blogs.msdn.com/remusrusanu/archive/2006/04/06/570578.aspx

It is important to mention the conversation lifetime role in these patterns. If a conversation is not ended by both sides before it's lifetime expires, the conversation is errored and an Error message is sent to any endpoint still open (not ended). This is why endpoints that still care about delivery of the last message sent cannot issue an END CONVERSATION. They are supposed to send the message and the if they get an EndDialog message is a confrmation of succesfull delivery, while an Error message is an indication of a problem.

As about the endpoint states, a 'Conversing' endpoint is an endpoint that did not receive nor sent an EndDialog message. All of the patterns I mention above clean up the endpoints after issuing the END CONVERSATION. The first endpoint that issues the END CONVERSATION will be kept in the system until the EndDialog message is acknowledged by the peer (in an DISCONNECTED_OUTBOUND state), then it will be closed. An endpoint that has received an EndDialog message will stay in DISCONNECTED_INBOUND state until is explictly ended with END CONVERSATION, then it will be closed.

When initiator endpoint is closed, the endpoint is immedeately deleted.

When target endpoint is closed, the endpoint might be kept around for up to 30 minutes to prevent a replay attack, then it will be deleted.

Another negative side effect of the fire-and-forget pattern is that the target endpoint is not kept for 30 minutes in that case, but until the original conversation lifetime expires. Since most application do not specify a lifetime, that mens the target is scheduled to be deleted 74 years from now, thus being leaked for all practical means.

HTH,

~ Remus

|||Thanks again Remus, this is perfect. I was confused about the dialogs getting cleaned up. I noticed that the WITH CLEANUP cleaned the dialog up, and that is what I wanted at the time. I have since taken this out of all of my code. I didn't realize that the dialogs got cleaned up after 30 minutes to prevent a replay attack. Thanks again for your help...I love this new feature of 2005.
Timsql

No comments:

Post a Comment