private async Task StartSub(ConsumerInfo consumer, bool first)
        {
            var child = new ConsumerChild
            {
                Channel = await client.PullModel(),
                Qos     = consumer.MinQos
            };

            if (first)
            {
                child.Channel.Model.ExchangeDeclare(consumer.Exchange, "direct", true);
                child.Channel.Model.QueueDeclare(consumer.Queue, true, false, false, null);
                child.Channel.Model.QueueBind(consumer.Queue, consumer.Exchange, consumer.RoutingKey);
            }
            child.Channel.Model.BasicQos(0, consumer.MinQos, false);

            child.BasicConsumer           = new EventingBasicConsumer(child.Channel.Model);
            child.BasicConsumer.Received += async(ch, ea) =>
            {
                await Process(consumer, child, ea, 0);
            };
            child.BasicConsumer.ConsumerTag = child.Channel.Model.BasicConsume(consumer.Queue, consumer.AutoAck, child.BasicConsumer);
            child.NeedRestart = false;
            consumer.Children.Add(child);
            consumer.NowQos   += child.Qos;
            consumer.StartTime = DateTime.UtcNow;
        }
        private async Task Process(ConsumerInfo consumer, ConsumerChild consumerChild, BasicDeliverEventArgs ea, int count)
        {
            if (count > 0)
            {
                await Task.Delay(count * 1000);
            }
            try
            {
                await consumer.Handler.Notice(ea.Body);

                if (!consumer.AutoAck)
                {
                    try
                    {
                        consumerChild.Channel.Model.BasicAck(ea.DeliveryTag, false);
                    }
                    catch
                    {
                        consumerChild.NeedRestart = true;
                    }
                }
            }
            catch (Exception exception)
            {
                logger.LogError(exception.InnerException ?? exception, $"An error occurred in {consumer.Exchange}-{consumer.Queue}");
                if (consumer.ErrorReject)
                {
                    consumerChild.Channel.Model.BasicReject(ea.DeliveryTag, true);
                }
                else
                {
                    if (count > 3)
                    {
                        consumerChild.NeedRestart = true;
                    }
                    else
                    {
                        await Process(consumer, consumerChild, ea, count + 1);
                    }
                }
            }
        }
        private async Task ExpandQos(ConsumerInfo consumer)
        {
            if (consumer.NowQos + consumer.IncQos <= consumer.MaxQos)
            {
                var child = new ConsumerChild
                {
                    Channel = await client.PullModel(),
                    Qos     = consumer.IncQos
                };
                child.Channel.Model.BasicQos(0, consumer.IncQos, false);

                child.BasicConsumer           = new EventingBasicConsumer(child.Channel.Model);
                child.BasicConsumer.Received += async(ch, ea) =>
                {
                    await Process(consumer, child, ea, 0);
                };
                child.BasicConsumer.ConsumerTag = child.Channel.Model.BasicConsume(consumer.Queue, consumer.AutoAck, child.BasicConsumer);
                child.NeedRestart = false;
                consumer.Children.Add(child);
                consumer.NowQos   += child.Qos;
                consumer.StartTime = DateTime.UtcNow;
            }
        }