MSMQ is asynchronous on the inside too
There is a new Knowledgebase article out - although I use the term "new" with some reservation. The article refers to a hotfix that has since been included in service pack 2 which gives you an idea how old the content really is.
So I'm not mentioning the KB article because you may need the fix as you will already have service pack 2 in place so would be a moot point (or not a moot point, depending how you use the English language).
What is instead interesting is why there is a problem. MSMQ is designed to shift messages as fast as possible between locations and everything else is a secondary function. So, in this article's case, a call is made to disconnect MSMQ. The application making the call immediately gets a "success" back as the queue manager accepts the request. Unfortunately that request will not necessarily be acted upon right away, depending on how busy the server is with incoming messages at the time.
An analogy would be with switching off a hose - it takes a while to turn the tap and stop the flow of water. In most cases that's not a problem but if we are talking about a fire hose then a lot of water can still pass through before the flow finally stops.
If, in the message queuing world, you are monitoring the health of the MSMQ server and are calling Disconnect to stop the volume of incoming messages reaching a particular level then that delay before disconnecting may be critical. There could be so many messages arriving per second that the server fills up and stops working (See this insufficient resources post for more detail on why) before the disconnection completes.
The resolutions are:
- Call Disconnect earlier than you need (although this is a bit hit and miss)
- Add the FastDisconnect registry value introduced in the KB article
Note that FastDisconnect is still not immediate (to allow any outstanding acknowledgements to arrive) but it is an improvement.