Skip to content

Instantly share code, notes, and snippets.

@neilgreatorex
Created December 24, 2021 15:21
Show Gist options
  • Save neilgreatorex/746c1d9af360ad4bcc5272ff6e645f6d to your computer and use it in GitHub Desktop.
Save neilgreatorex/746c1d9af360ad4bcc5272ff6e645f6d to your computer and use it in GitHub Desktop.
RabbitMQ channel leak
namespace ConsoleApp
{
using System;
using System.Collections.Generic;
using RabbitMQ.Client;
class Program
{
static void Main(string[] args)
{
var connectionFactory = new ConnectionFactory
{
HostName = "localhost",
UserName = "guest",
Password = "guest",
AutomaticRecoveryEnabled = true,
ClientProvidedName = "Channel leak test",
ContinuationTimeout = TimeSpan.FromSeconds(5)
};
var connection = connectionFactory.CreateConnection();
connection.ConnectionBlocked += (sender, eventArgs) => Log("*** Connection blocked!");
connection.ConnectionUnblocked += (sender, eventArgs) => Log("*** Connection unblocked!");
connection.ConnectionShutdown += (sender, eventArgs) => Log("*** Connection shutdown!");
TestSimplePublish(connection);
TestMultipleChannelOpen(connection);
Do("close connection", () => connection.Close(TimeSpan.FromSeconds(15)));
Do("dispose connection", () => connection.Dispose());
}
private static void TestMultipleChannelOpen(IConnection connection)
{
List<IModel> channels = new List<IModel>();
for (var i = 1; i <= 5; i++)
{
try
{
Do($"open channel {i}", () => channels.Add(connection.CreateModel()));
}
catch (TimeoutException e)
{
Log($"*** Timeout exception for channel {i}");
}
}
Log($"{channels.Count} channel references held");
WaitForInput("check channel count");
WaitForInput("clear broker resource constraint, re-check channel count");
channels.ForEach(channel => Do("abort channel", channel.Abort));
channels.Clear();
Do("collect garbage", GC.Collect);
WaitForInput("check channel count again");
}
private static void Do(string message, Action action)
{
Log($"About to '{message}'");
action();
Log($"Finished '{message}'");
}
private static void Log(string message)
{
Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}: {message}");
}
private static void WaitForInput(string message)
{
Console.WriteLine($"Please {message} and then press any key to continue...");
Console.ReadKey();
}
private static void TestSimplePublish(IConnection connection)
{
IModel model = null;
Do("open publish channel", () => model = connection.CreateModel());
Do("declare exchange", () => model.ExchangeDeclare("test_exchange", "direct", autoDelete: true));
Do("publish message", () => model.BasicPublish("test_exchange", "test"));
Do("close publish channel", () => model.Close());
Do("dispose publish channel", () => model.Dispose());
}
}
}
2021-12-24 15:10:37.209: About to 'open publish channel'
2021-12-24 15:10:37.258: Finished 'open publish channel'
2021-12-24 15:10:37.258: About to 'declare exchange'
2021-12-24 15:10:37.259: Finished 'declare exchange'
2021-12-24 15:10:37.259: About to 'publish message'
2021-12-24 15:10:37.261: Finished 'publish message'
2021-12-24 15:10:37.261: About to 'close publish channel'
2021-12-24 15:10:37.262: *** Connection blocked!
2021-12-24 15:10:47.270: Finished 'close publish channel'
2021-12-24 15:10:47.270: About to 'dispose publish channel'
2021-12-24 15:10:47.271: Finished 'dispose publish channel'
2021-12-24 15:10:47.271: About to 'open channel 1'
2021-12-24 15:10:52.297: *** Timeout exception for channel 1
2021-12-24 15:10:52.298: About to 'open channel 2'
2021-12-24 15:10:57.309: *** Timeout exception for channel 2
2021-12-24 15:10:57.309: About to 'open channel 3'
2021-12-24 15:11:02.334: *** Timeout exception for channel 3
2021-12-24 15:11:02.335: About to 'open channel 4'
2021-12-24 15:11:07.351: *** Timeout exception for channel 4
2021-12-24 15:11:07.351: About to 'open channel 5'
2021-12-24 15:11:12.374: *** Timeout exception for channel 5
2021-12-24 15:11:12.374: 0 channel references held
Please check channel count and then press any key to continue...
PS C:\Program Files\RabbitMQ Server\rabbitmq_server-3.9.11\sbin> .\rabbitmqctl.bat list_channels
Listing channels ...
pid user consumer_count messages_unacknowledged
<rabbit@laptop.1640256637.4113.1> guest 0 0
Please clear broker resource constraint, re-check channel count and then press any key to continue...
PS C:\Program Files\RabbitMQ Server\rabbitmq_server-3.9.11\sbin> .\rabbitmqctl.bat set_vm_memory_high_watermark absolute "1G"
Setting memory threshold on rabbit@laptop to 1G bytes ...
2021-12-24 15:14:09.062: *** Connection unblocked!
PS C:\Program Files\RabbitMQ Server\rabbitmq_server-3.9.11\sbin> .\rabbitmqctl.bat list_channels
Listing channels ...
pid user consumer_count messages_unacknowledged
<rabbit@laptop.1640256637.4413.1> guest 0 0
<rabbit@laptop.1640256637.4418.1> guest 0 0
<rabbit@laptop.1640256637.4423.1> guest 0 0
<rabbit@laptop.1640256637.4428.1> guest 0 0
<rabbit@laptop.1640256637.4433.1> guest 0 0
2021-12-24 15:15:46.141: About to 'collect garbage'
2021-12-24 15:15:46.142: Finished 'collect garbage'
Please check channel count again and then press any key to continue...
PS C:\Program Files\RabbitMQ Server\rabbitmq_server-3.9.11\sbin> .\rabbitmqctl.bat list_channels
Listing channels ...
pid user consumer_count messages_unacknowledged
<rabbit@laptop.1640256637.4413.1> guest 0 0
<rabbit@laptop.1640256637.4418.1> guest 0 0
<rabbit@laptop.1640256637.4423.1> guest 0 0
<rabbit@laptop.1640256637.4428.1> guest 0 0
<rabbit@laptop.1640256637.4433.1> guest 0 0
2021-12-24 15:16:31.981: About to 'close connection'
2021-12-24 15:16:31.984: *** Connection shutdown!
2021-12-24 15:16:31.987: Finished 'close connection'
2021-12-24 15:16:31.988: About to 'dispose connection'
2021-12-24 15:16:31.997: Finished 'dispose connection'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment