Example #1
0
    public static void Main()
    {
        RabbitMqConsoleEventListener loggingEventSource = new RabbitMqConsoleEventListener();

        // Set default interval for heartbeats
        // Reduce the heartbeat interval so that bad connections are detected sooner than the default of 60s
        ushort heartbeatInterval = 20;

        if (ushort.TryParse(Environment.GetEnvironmentVariable("HEARTBEAT_INTERVAL_SEC"), out heartbeatInterval))
        {
            Console.WriteLine("Setting heartbeat interval from HEARTBEAT_INTERVAL_SEC");
        }
        else
        {
            Console.WriteLine("HEARTBEAT_INTERVAL_SEC environment variable not defined, using default.");
            heartbeatInterval = 20;
        }
        Console.WriteLine("Setting heartbeat interval to {0} s", heartbeatInterval);

        int port = 5670;

        if (int.TryParse(Environment.GetEnvironmentVariable("RABBITMQ_NODE_PORT"), out port))
        {
            Console.WriteLine("Setting port from RABBITMQ_NODE_PORT");
        }
        else
        {
            port = 5670;
        }
        Console.WriteLine("Port: {0}", port);

        if (Environment.GetEnvironmentVariable("VCAP_SERVICES") == null)
        {
            // Not running on Cloud Foundry
            factory = new ConnectionFactory()
            {
                HostName = "localhost",
                UserName = "******",
                Password = "******",
                Port     = port,
                AutomaticRecoveryEnabled = true,
                RequestedHeartbeat       = heartbeatInterval
            };
        }
        else
        {
            // Running on PCF
            services = new ServiceCollection();
            var config = new ConfigurationBuilder()
                         .AddEnvironmentVariables()
                         .AddCloudFoundry()
                         .Build();
            services.AddRabbitConnection(config);
            factory = services.BuildServiceProvider().GetService <ConnectionFactory>();
        }

        taskQueueName = Environment.GetEnvironmentVariable("QUEUE_NAME");
        if (taskQueueName == null)
        {
            taskQueueName = "task_queue";
        }
        Console.WriteLine("Setting queue name to {0}", taskQueueName);

        // Since we have a durable queue anyways, there should be no need to recreate it on a connection failure.
        // Otherwise this currently can result in exceptions (if the durable queue home node is down), that
        // hangs the RMQ client.
        if (bool.TryParse(Environment.GetEnvironmentVariable("TOPOLOGY_RECOVERY_ENABLED"), out enableTopologyRecovery))
        {
            Console.WriteLine("Setting topology recovery from TOPOLOGY_RECOVERY_ENABLED");
        }
        else
        {
            enableTopologyRecovery = true;
        }
        factory.TopologyRecoveryEnabled = enableTopologyRecovery;
        Console.WriteLine("Topology recovery enabled: {0}", factory.TopologyRecoveryEnabled);

        using (connection = factory.CreateConnection())
        {
            // An autorecovery occurred
            connection.RecoverySucceeded += (sender, e) =>
            {
                if (enableTopologyRecovery)
                {
                    /*
                     * Note: if consumer.IsRunning is false here, it could just be because the Registered event
                     * has not yet fired for the recovered consumer
                     */
                    Console.WriteLine("RecoverySucceeded, now waiting on Registered event - ThreadId: {0}",
                                      Thread.CurrentThread.ManagedThreadId);
                    if (consumerRegistered.Wait(factory.ContinuationTimeout))
                    {
                        Console.WriteLine("RecoverySucceeded, consumer restarted - Consumer tag: {0} IsRunning: {1}",
                                          consumer.ConsumerTag, consumer.IsRunning);
                    }
                    else
                    {
                        Console.WriteLine("RecoverySucceeded, consumer did not restart! - Consumer tag: {0}",
                                          consumer.ConsumerTag);
                        CreateConsumer(taskQueueName);
                    }
                }
                else
                {
                    /*
                     * Without topology recovery enabled, we are forced to create a new consumer
                     */
                    Console.WriteLine("RecoverySucceeded, topology recovery disabled, creating a new consumer");
                    CreateConsumer(taskQueueName);
                }
            };

            using (channel = connection.CreateModel())
            {
                channel.CallbackException += (sender, e) => Console.WriteLine(e.Exception);
                channel.ModelShutdown     += (sender, e) => Console.WriteLine($"Channel closed: {e.Cause?.ToString()}");

                channel.QueueDeclare(queue: taskQueueName,
                                     durable: true, exclusive: false,
                                     autoDelete: false, arguments: null);

                Console.WriteLine("Creating initial consumer and waiting for Registered...");
                CreateConsumer(taskQueueName);
                if (consumerRegistered.Wait(factory.ContinuationTimeout))
                {
                    Console.WriteLine("Initial consumer started - Consumer tag: {0} IsRunning: {1}",
                                      consumer.ConsumerTag, consumer.IsRunning);
                    while (true)
                    {
                        consumerLock.EnterReadLock();
                        try
                        {
                            Console.WriteLine("Current consumer tag: {0} IsRunning: {1} ThreadId: {2}",
                                              consumer.ConsumerTag, consumer.IsRunning,
                                              Thread.CurrentThread.ManagedThreadId);
                        }
                        finally
                        {
                            consumerLock.ExitReadLock();
                        }
                        Thread.Sleep(TimeSpan.FromSeconds(5));
                    }
                }
                else
                {
                    Console.WriteLine("Initial consumer did not start!");
                }
            }
        }
    }
Example #2
0
    public static void Main(string[] args)
    {
        RabbitMqConsoleEventListener loggingEventSource = new RabbitMqConsoleEventListener();

        int numMsgsPublished = 1;

        // Set default interval to publish messages
        ushort heartbeatInterval    = 20;
        string heartbeatIntervalStr = Environment.GetEnvironmentVariable("HEARTBEAT_INTERVAL_SEC");

        if (heartbeatIntervalStr == null)
        {
            Console.WriteLine("HEARTBEAT_INTERVAL_SEC environment variable not defined, using default.");
        }
        else
        {
            heartbeatInterval = Convert.ToUInt16(heartbeatIntervalStr);
        }

        Console.WriteLine("Setting heartbeat interval to {0} s", heartbeatInterval);

        // Set default interval to publish messages
        int    publishIntervalSec = 600;
        string publishIntervalStr = Environment.GetEnvironmentVariable("PUBLISH_INTERVAL_SEC");

        if (publishIntervalStr == null)
        {
            Console.WriteLine("PUBLISH_INTERVAL_SEC environment variable not defined, using default.");
        }
        else
        {
            publishIntervalSec = Convert.ToInt32(publishIntervalStr);
        }

        Console.WriteLine("Message publish interval is {0} s", publishIntervalSec);
        int publishInterval = publishIntervalSec * 1000;

        int    port    = 5672;
        string portStr = Environment.GetEnvironmentVariable("RABBITMQ_NODE_PORT");

        if (portStr != null)
        {
            port = Convert.ToInt32(portStr);
        }

        var factory = new ConnectionFactory()
        {
            HostName = "localhost", Port = port
        };

        if (Environment.GetEnvironmentVariable("VCAP_SERVICES") != null)
        {
            // Running on PCF
            IServiceCollection services = new ServiceCollection();
            var config = new ConfigurationBuilder()
                         .AddEnvironmentVariables()
                         .AddCloudFoundry()
                         .Build();
            services.AddRabbitConnection(config);
            factory = services.BuildServiceProvider().GetService <ConnectionFactory>();
        }


        taskQueueName = Environment.GetEnvironmentVariable("QUEUE_NAME");
        if (taskQueueName == null)
        {
            taskQueueName = "task_queue";
        }
        Console.WriteLine("Setting queue name to {0}", taskQueueName);

        // No need to explicitly set this value, default is already true
        // factory.AutomaticRecoveryEnabled = true;

        // Since we have a durable queue anyways, there should be no need to recreate it on a connection failure.
        // Otherwise this currently can result in exceptions (if the durable queue home node is down), that
        // hangs the RMQ client.
        factory.TopologyRecoveryEnabled = false;

        // Reduce the heartbeat interval so that bad connections are detected sooner than the default of 60s
        factory.RequestedHeartbeat = heartbeatInterval;

        using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare(queue: taskQueueName, durable: true, exclusive: false, autoDelete: false, arguments: null);

                var message = "Happy Birthday!!";
                var body    = Encoding.UTF8.GetBytes(message);

                var properties = channel.CreateBasicProperties();
                properties.Persistent = true;

                while (true)
                {
                    channel.BasicPublish(exchange: "", routingKey: taskQueueName, basicProperties: properties, body: body);
                    Console.WriteLine("Published {0} messages", numMsgsPublished++);
                    Thread.Sleep(publishInterval);
                }
            }
    }