Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RabbitMQ Client (DotNet Core) preventing application from closing

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)?

like image 270
Tim Gray Avatar asked Oct 14 '25 02:10

Tim Gray


1 Answers

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
        );
    }
like image 117
Tim Gray Avatar answered Oct 17 '25 22:10

Tim Gray