The goal: Reliable transport of continuously generated records to the central SQL.
Summary: The satellite needs to ask the central what are the latest data on its side, and then it is going to send continuously newer ones.
The satellite SQL server may be (re)started sometimes (related to physicall production machine), the central SQL machine is likely to run longer, but there also can be some downtime. The lines are mostly reliable, but one never knows... I expect the connection problems be solved naturally by the SQL Server Service Broker. However, I need to solve the problem of the initial handshake and sending the data. I need to design the protocol and my SSB knowledge is still poor.
I hope I understand the basics of communication using SSB that are nicely and briefly described as
You should start with each work item on its own conversation. The producer (initiator) begins a dialog and send the message describing the work item, then commits. The consumer (target) receives the message (or gets activated), inspects the payload to understand the work item details, executes the work, then ends the dialog and commit. The resulting EndDialog message gets sent back to the initiator service queue, and an activated procedure on the initiator queue responds to it by ending the dialog on the initiator side.
... by Remus Rusanu (if interested see more details in his earlier answer).
I would like to send the records as XML messages like this (a multiline string here)
<row a="1" b="11" c="111" />
<row a="2" b="22" c="222" />
<row a="3" b="33" c="333" />
<row a="4" b="44" c="444" />
and I have already learned how to write the SELECT
to obtain the info from the XML message.
The communication: Say the communication mechanism between the SQL servers was just activated...
The satellite SQL obtained new data, and somehow it knows that there is no pending message between the satellite and the central. But it also does not know what data was already sent to the central. Therefore it has to ask the central what is its the last available data.
If I understand the
END CONVERSATION
correctly, the command causes sending only a kind of empty messageN'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
. Because of this, the central should probably send my typeReplyMessage
with the answer back before theEND CONVERSATION
.Meanwhile, the satellite should probably do nothing to behave asychronously (i.e. waits after sending the
RequestMessage
). Once theReplyMessage
arrives, it activates a satellite procedure that:- receives the message and get the wanted information,
- receives the EndDialog message and ends the previous dialog at the satellite side,
- prepares the data to be sent to the central (the XML string form),
- opens the new dialog,
- sends the prepared data,
- and makes itself dormant until another
ReplyMessage
arrives.
The central should behave similarly. Once the
RequestMessage
arrives, it activates the central procedure that:- receives the request message,
- extracts the XML information and updates the central database,
- gets the info about the last available data for the satellite,
- forms and sends the
ReplyMessage
, - ends the dialog at the central side.
So far, is my view correct?
Now some details that I am not sure about: As I want to make it robust, working without a human touch, it should start on its own when the mechanism is installed. The communication should always be started by the satellite (the central may not know even if the satellite works or even exists).
The satellite already uses a trigger fired by a raw data that is processed to build the records that are collected at the central. This way, the trigger could initiate somehow the first SSB request of the satellite to the central. But...
- How the trigger can check that there is no pending communication between the satellite and the central? As the satellite is always the initiator, the question can also be formulated as... How the trigger can check whether the satellite waits for some
ReplyMessage
? Or, how to know that there is some open dialog between the satellite and the central?- If there is no conversation, the trigger forms the data record (stored in a local table), and then it could start the communication proces (see the point 1 above).
- If there is any conversation, the trigger only forms the record that is to be sent later, and nothing else is done. Data will be sent when the
ReplyMessage
is obtained by the activated procedure (see the point 3 above).
- On making the satellite dormant (see the last bullet of the point 3 above) I mean that there should probably be no other message in the message queue (nothing to be processed in the loop) and the activated procedure is to be naturally finished. But I am not sure if I think correctly here. Can you comment on that?
- If nothing is broken, and if the data is produced fast enough, the satellite and the central have always something to exchange. This way, the trigger should never try to start the communication.
- When there is nothing else to be sent to the central by the activated satellite procedure (actually, it is not active), or when the system is restarted somehow (no dialog exists yet), the trigger starts the communication process. But how could I do it? Should the trigger simply send the
RequestMessage
to the central? (This way theReplyMessage
would activate the satellite procedure and the procedure would continue until there is anything to process.) - Say, the
RequestMessage
means here is some data, process them, and reply what is the last (or what next should be send or what next action is recommended from the central -- depends on the bussiness logic, probably not important here). Is it OK to send empty XML in theRequestMessage
in the sense I do not know what else you need -- tell me?
First update -- based on the Remus Rusanu's answer below.
I have to agree that this would be chatty protocol. Moreover, the records are created as temperature samples from the real environment and the frequency of sampling is rather low. This means that the complicated protocol could be usefull only in the special case of restarting everything or so.
But when the conversation should be left open forever, the unique identifier for the dialog handle or should be stored persistently in some configuration table, or it could even be hardwired to the code. The trigger will send the records on the fly immediately, and the central will simply not send the ReplyMessage
. Is it correct? Can that kind of coversation be effectively considered a monolog?
Second update to make this question reasonably short.
See the continuation Service Broker: How should a trigger start infinitely opened dialog?