I was having problem with memory leak in assembly RabbitMQ.Client
- .NET client for RabbitMQ after enabling automatic recovery of connections and topology.
There were retained objects: RabbitMQ.Client.Framing.Impl.AutorecoveringConnection (more specifically there were dictionaries System.Collections.Generic.Dictionary<String, RecordedConsumer>
and System.Collections.Generic.Dictionary<String, RecordedQueue>
).
I've found useful info in Java client documentation for RabbitMQ client:
However, the client cannot track these topology changes beyond a single connection. Applications that rely on auto-delete queues or exchanges, as well as queue TTL (note: not message TTL!), and use automatic connection recovery, should explicitly delete entities know to be unused or deleted, to purge client-side topology cache.
So I've decided to delete it from client's cache right after calling to QueueDeclareOk QueueDeclare(string queue, bool durable, bool exclusive, bool autoDelete, IDictionary<string, object> arguments);
I do it like this:
/// <summary>
/// Removes a queue from client's autorecovery cache when it's needed.
/// </summary>
private void DeleteFromRecordedQueues(string queue, IDictionary<string, object> queueArgs)
{
if (!RabbitMqUtils.IsTemporaryQueue(queueArgs))
return;
var autoRecoveringConnection = connection as AutorecoveringConnection;
if (autoRecoveringConnection == null)
return;
autoRecoveringConnection.DeleteRecordedQueue(queue);
}
Approximately the same I do for consumer, using this method public RecordedConsumer DeleteRecordedConsumer(string consumerTag)
This approach is OK for short-living queues, But what if my queue time-to-live is set to a long period (for example 30 minutes), and I want it to auto-recover in case of network problems?
My colleague suggested that I use job, checking RecordedQueues
against all queues existing on the server, and run my DeleteFromRecordedQueues
in case it does not exist anymore. But I do not like this solution as I believe this problem must be solved using standard client library fuctionality.
Is it possible to escape memory leak and not lose autorecovery functionality for the auto-delete queue?