I have a piece of code that is using rabbitMQ to manage lists of jobs over time. As such I have a connection and a channel open to the RabbitMQ Server to do operations with these jobs. I queue jobs with the following:
public override void QueueJob(string qid, string jobId) {
this.VerifyReadyToGo();
this.CreateQueue(qid);
byte[] messageBody = Encoding.UTF8.GetBytes(jobId);
this.channel.BasicPublish(
exchange: Exchange,
routingKey: qid,
body: messageBody,
basicProperties: null
);
OLog.Debug($"Queued job {jobId} on {qid}");
}
public override string RetrieveJobID(string qid) {
this.VerifyReadyToGo();
this.CreateQueue(qid);
BasicGetResult data = this.channel.BasicGet(qid, false);
string jobData = Encoding.UTF8.GetString(data.Body);
int addCount = 0;
while (!this.jobWaitingAck.TryAdd(jobData, data.DeliveryTag)) {
// try again.
Thread.Sleep(10);
if (addCount++ > 2) {
throw new JobReceptionException("Failed to add job to waiting ack list.");
}
}
OLog.Debug($"Found job {jobData} on queue {qid} with ackId {data.DeliveryTag}");
return jobData;
}
The issue is that after any method call like this (Publish, Get, or Acknowledge) creates some sort of background thread that does not close when the channel and connection are closed. This means that tests pass and the operations complete successfully but when the application tries to close it hangs and does not ever finish.
Here is the connect method for reference
public override void Connect() {
if (this.Connected) {
return;
}
this.factory = new ConnectionFactory {
HostName = this.config.Hostname,
Password = this.config.Password,
UserName = this.config.Username,
Port = this.config.Port,
VirtualHost = VirtualHost
};
this.connection = this.factory.CreateConnection();
this.channel = this.connection.CreateModel();
this.channel.ExchangeDeclare(
exchange: Exchange,
type: "direct",
durable: true
);
}
What can I do to correct this issue (rabbitmq client preventing application from exiting)?
I have no idea why but this change to the Connect method makes the difference:
public override void Connect() {
if (this.Connected) {
return;
}
this.factory = new ConnectionFactory {
HostName = this.config.Hostname,
Password = this.config.Password,
UserName = this.config.Username,
Port = this.config.Port,
UseBackgroundThreadsForIO = true
};
this.connection = this.factory.CreateConnection();
this.channel = this.connection.CreateModel();
this.channel.ExchangeDeclare(
exchange: Exchange,
type: "direct",
durable: true
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With