May 30, 2010 at 9:20 pm
I started looking at Service Broker for processing a message queue in a single-threaded asynchronous fashion. My initial testing more or less works, but I'm always getting an orphan target conversation endpoint. The most basic example is effectively from Adam Mechanic's first SimpleTalk Workbench on Service Broker[/url]. I've snipped abbreviated code below, which is what I'm running.
-- setup message, contract, queues, and services
CREATE MESSAGE TYPE Simple_Msg
VALIDATION = WELL_FORMED_XML
GO
CREATE CONTRACT Simple_Contract
(Simple_Msg SENT BY ANY)
GO
CREATE QUEUE Simple_Queue_Init
CREATE QUEUE Simple_Queue_Target
GO
CREATE SERVICE Simple_Service_Init
ON QUEUE Simple_Queue_Init
(Simple_Contract)
CREATE SERVICE Simple_Service_Target
ON QUEUE Simple_Queue_Target
(Simple_Contract)
GO
DECLARE @init UNIQUEIDENTIFIER, @target UNIQUEIDENTIFIER
-- init opens conversation
BEGIN DIALOG CONVERSATION @init
FROM SERVICE Simple_Service_Init
TO SERVICE 'Simple_Service_Target'
ON CONTRACT Simple_Contract
WITH ENCRYPTION=OFF
-- init sends message
;SEND ON CONVERSATION @init
MESSAGE TYPE Simple_Msg
('<Hello_Simple_Talk/>')
-- target receives message
;RECEIVE @target = conversation_handle FROM Simple_Queue_Target
-- target sends reply
;SEND ON CONVERSATION @target
MESSAGE TYPE Simple_Msg
('<Goodbye_Simple_Talk/>')
-- target closes
END CONVERSATION @target
-- init receives message
;RECEIVE * FROM Simple_Queue_Init
-- init closes
END CONVERSATION @init
SELECT * FROM sys.conversation_endpoints
SELECT * FROM Simple_Queue_Init
SELECT * FROM Simple_Queue_Target
GO
-- cleanup
DROP SERVICE Simple_Service_Init
DROP SERVICE Simple_Service_Target
DROP QUEUE Simple_Queue_Init
DROP QUEUE Simple_Queue_Target
DROP CONTRACT Simple_Contract
DROP MESSAGE TYPE Simple_Msg
GO
After running that, I always end up with the target's endpoint showing up, but in a CLOSED state. I have to run END CONVERSATION WITH CLEANUP to get rid of it.
When I first started doing this, it was in a fire-and-forget fashion. For my purposes, there is no response. So long as the message gets in the queue, that's all that matters. When I noticed the orphans, I read that what I was doing was considered very bad by people who had worked with SSB for longer than the two hours I had. The target should always close the conversation. I can deal with that if that's the case, but the above example still has the same orphan problem. What am I doing wrong?
June 28, 2010 at 1:51 am
Hi Andrew
When you initiate a conversation between two queues, you actually end up with two conversation handles. One used by the sender queue to address the sender, and another used by the receiver queue to receive messages from the sender.
When you close the converation from the sender, a message will also be sent to the receiver with a message type name of "http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog"
When you receive that message on the receiver queue, you have to close the conversation that it is part of.
What some other people do for applications like yours (which are essentially fire and forget scenarios), is to only ever use a single conversation, or a few possible conversations if you want to allow multi-threaded receives. This conversation is never closed, so there are no oprhan dialogs.
HTH
Joon
Viewing 2 posts - 1 through 1 (of 1 total)
You must be logged in to reply to this topic. Login to reply