QPID.net oddities
I noticed a couple of odd behavior in the QPID.net implementation so figured I’d document them here.
First, the code…
_client = new Client();
_client.connect( host, port, virtualHost, userName, password );
_session = _client.createSession( -1 );
// Create a response queue so the server can send us responses
_responseQueue = string.Format( "GUI_{0}_{1}", Environment.UserName, DateTime.Now.Ticks );
// Use the name of the response queue as the routing key
_session.queueDeclare( _responseQueue, new Option[] {
// Setting EXCLUSIVE option makes the queue hang around
// even when the session is closed
Option.AUTO_DELETE //, Option.EXCLUSIVE
} );
_session.exchangeBind( _responseQueue, "amq.direct", _responseQueue );
- Apparently, specifying Option.Exclusive on the queue, as the comment indicates, causes the queue to hang around even after you cleanly tear down the session and connection. (You can use qpid-stat to find out about the open sessions;
qpid-stat -q localhost:6001 -S queue
with the port where your daemon is listening to, of course.) - Even though I’m not specifying a timeout when creating the session, and given that QPID sessions typically are set to infinite timeouts, the session is closed by the broker after some period of inactivity. You’ll notice that the session has closed the next time you attempt to send a message back to the server. (If you have QPID configured to log everything, you can easily search the log file for your IP address to see if it’s disconnected; you should see entries similar to the following)
debug DISCONNECTED [10.1.223.77:3356]For now, until I find a better solution, to fix this requires a hack. Essentially, you need to check whether the session is closed or not before attempting to send a message (code below). You’ll notice a Sleep call which I found was necessary as sending a message immediately after the session connects causes it to go into the ether
///
/// HACK! Attempt to reconnect if the session was closed.
/// TODO Find a way to keep the session open
///
protected void CheckSessionState() {
if (_session != null && _session.Closed == false)
return;
bool isConnected = false;
int tryCnt = 5, i = 0;
while (!isConnected && i < tryCnt) {
OnMessageWorkerLogMessage(this.GetServiceName() + " was closed, attempting to reconnect");
Disconnect();
Connect(this.Host, this.Port, this.VirtualHost, _user, _pwd);
Thread.Sleep(100);
isConnected = _session != null && (_session.Closed == false);
i++;
if (isConnected) {
break;
}
OnMessageWorkerLogMessage(this.GetServiceName() +
(isConnected ? " reconnected" :
" still closed. Attempting " + (tryCnt - 1 - i) + " more times"));
}
}
Categories: .net