views:

60

answers:

3

I am in the process of designing a system where i need to keep on trying to connect to MQ server unitl i get a connection.

By default if the MQ is not availlble it will thorugh exception. How can call the same method again and again until i get the connection. I know i can use recursion, is there any better way to do it . Becuase i would like to avoid infinite loops. I also want to wait the the furthere processing until i get connection.

I am using .net 2.0 with C#. It is window Service application.

+2  A: 

Here is the basic structure:

while(true)
{
  try
  {
    // attempt connection
    break; // Will only get here if an exception was not thrown
  }
  catch
  {
    // Logging, sleep statement
  }
}

If you have any method of finding out if a connection cannot be made (other then an exception being thrown), use that. Exceptions should not be used for flow-control, and the example I have shown is for extreme cases.

To avoid the loop being infinite, you may want to add counts (only attempt 10 times, for example).

Oded
This is how you "can" do it, whether you should allow infinite calls is another issue. Personally, I would put some sort of sleep after the catch (at least 1ms) to calm the cpu usage of it, and probably have a max number of times to fail. Good answer though, it fit what they wanted.
Tom Anderson
That sleep should be a full second or more. If the client reconnect loop is too fast, it will use up the WMQ listener backlog at which point no remote connection from any client or peer QMgr will succeed.
T.Rob
+3  A: 

The way I see it, the loop should be infinite. Would you want to be the guy who has to restart the service because the server was down for 45 minutes?

const int attempts = 3;
const int perAttemptSleep = 5000;
const int perTrialSleep = 600000;

while (true)
{
    for (var i = 0; i < attempts; i++)
    {
        try
        {
            Connect();
            return;
        }
        catch (ConnectException)
        {
            Thread.Sleep(perAttemptSleep);
        }
    }

    Log();
    Thread.Sleep(perTrialSleep);
}
ChaosPandion
@Oded nope: it will wait the time defined by `perTrialSleep` and then re-enter the `for` block, resetting `i` and trying 3 more times.
herenvardo
+1  A: 

The code samples already provided will get you the looping you need so I won't duplicate that advice. However, I have a few suggestions.

The .Net functionality in WMQ v7.0 is much better than in WMQ v6. Among the options available are that client reconnection can be handled entirely in channel configuration. Since v6 is End-of-Life as of Sept 2011 and this is a new application, I would highly recommend using the WMQ v7 client. You can use it with a v6 QMgr but won't get all the v7 functionality. Preferably you can use a v7 QMgr as well, then you get the reconnection behavior as a configurable option. If you go with v6 now you will need to upgrade to v7 in the next 18 months if you want to be able to get support from IBM.

IBM - MQC7: WebSphere MQ V7.0 Clients http://bit.ly/bXM0q3

Assuming you will proceed with coding reconnection logic, you definitely want to sleep for at least a full second, and preferably several seconds, between reconnection attempts. Failure to do so will flood the WMQ listener and execute a very effective denial of service attack.

Be sure to include the WMQ reason codes in the log messages. For example, if you are trying to put a message on a queue and get back a 2053 MQRC_Q_FULL it is usually a transient error caused by a fast-producer/slow-consumer problem. But if you get back 2035 MQRC_AUTHORIZATION_ERROR then there's no chance of the program recovering without human intervention. If the logged messages do not have the WMQ reason code, it is very difficult to determine the root cause of errors in the transport layer.

T.Rob
Thx that helps.