Orphan conversation endpoints

  • 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?

  • 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