예제 #1
0
        /// <summary>
        /// Registers task and starts consuming messages
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="queueName"></param>
        /// <param name="OnConsume"></param>
        public void ConsumeTask <T>(string queueName, Func <T, TaskParameters, ClientActiveTasks, Task> OnConsume, Func <ClientActiveTasks, int> PostConsumeCleanup, ushort concurrency)
        {
            // Caution. The queue is also declard inside PublishTask above
            _logger.LogInformation("Prefetch concurrency count {0}", concurrency);
            lock (_channel)
            {
                _channel.QueueDeclare(queue: queueName,
                                      durable: true,
                                      exclusive: false,
                                      autoDelete: false,
                                      arguments: null);
                // See https://www.rabbitmq.com/consumer-prefetch.html
                // See https://stackoverflow.com/questions/59493540/what-is-prefetchsize-in-rabbitmq

                _channel.BasicQos(prefetchSize: 0, prefetchCount: concurrency, global: false);
            }

            _logger.LogInformation(" [*] Waiting for messages, queueName - {0}", queueName);

            var consumer = new EventingBasicConsumer(_channel);

            consumer.Received += async(model, ea) =>
            {
                // This object exists so that we can wrap all OnConsumes with a try-finally here
                // And during the finally block remove the task from the set of active tasks
                // At this level of the code we don't have the specific task information
                // Instead the specific task my register a task by calling register
                ClientActiveTasks clientCleanup = new ClientActiveTasks();

                var taskObject = CommonUtils.BytesToMessage <TaskObject <T> >(ea.Body);
                _logger.LogInformation(" [x] {0} Received {1}", queueName, taskObject.ToString());
                // TODO: Update JobStatus table here (started timestamp)
                try
                {
                    await OnConsume(taskObject.Data, taskObject.TaskParameters, clientCleanup);
                }
                catch (Exception e)
                {
                    _logger.LogError(e, "Error occured in RabbitMQConnection {0} for message {1}", queueName, taskObject.ToString());
                }
                finally
                {
                    PostConsumeCleanup(clientCleanup);
                }
                _logger.LogInformation(" [x] {0} Done {1}", queueName, taskObject.ToString());
                // TODO Update JobStatus table here (including timestamp +  result + exception if it occurred)
                lock (_channel)
                {
                    _channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
                }
            };
            lock (_channel)
            {
                _channel.BasicConsume(queue: queueName,
                                      autoAck: false,
                                      consumer: consumer);
            }
        }
예제 #2
0
 public ClientActiveTasks(ClientActiveTasks source) : base(source)
 {
 }