Ejemplo n.º 1
0
        static async Task Main(string[] args)
        {
            _logger = Core.Logger.Logger.BuildLogger();

            var cts = new CancellationTokenSource();

            _logger.Information("Consumindo mensagens do Kafka");

            Console.CancelKeyPress += (_, e) =>
            {
                e.Cancel = true;
                cts.Cancel();
            };

            var config = new ConsumerConfig
            {
                BootstrapServers      = Constants.BootstrapServers,
                GroupId               = Constants.GroupId,
                AutoOffsetReset       = AutoOffsetReset.Earliest,
                Acks                  = Acks.All,
                EnableAutoCommit      = true,
                EnableAutoOffsetStore = false
            };


            try
            {
                using (var consumer = new ConsumerBuilder <Ignore, string>(config)
                                      .SetStatisticsHandler((_, json) => _logger.Information($"Statistic: {json}"))
                                      .SetLogHandler((_, log) => _logger.Information($"Log: {log}"))
                                      .Build())
                {
                    consumer.Subscribe(Constants.TopicName);


                    try
                    {
                        while (true)
                        {
                            var commitMessage = true;
                            var cr            = consumer.Consume(cts.Token);

                            var message = JsonConvert.DeserializeObject <EmailMessage>(cr.Message.Value);

                            var topicPartitions = new List <TopicPartition>()
                            {
                                { cr.TopicPartition }
                            };

                            try
                            {
                                var now = DateTime.Now;

                                _logger.Information($"===========================================================");
                                _logger.Information($"Hora atual: {now}");

                                if (DateTime.Compare(now, message.Timestamp) == -1)
                                {
                                    var waitTime = ((TimeSpan)(message.Timestamp - now)).TotalMilliseconds;

                                    _logger.Warning($"Hora que deve processar: {message.Timestamp}. Esperar: {waitTime} ms");

                                    consumer.Pause(topicPartitions);

                                    await Task.Delay(TimeSpan.FromMilliseconds(waitTime));

                                    consumer.Resume(topicPartitions);

                                    //commitMessage = await SendMessageToRetryTopic(message);
                                }

                                await ProcessMessage(message);
                            }
                            catch (MyKafkaException kex)
                            {
                                _logger.Error($"Erro interno: {kex.Message}");
                                _logger.Information("Enviando para retry topic.");
                                commitMessage = await SendMessageToRetryTopic(message, true);
                            }
                            finally
                            {
                                if (commitMessage)
                                {
                                    consumer.StoreOffset(cr);
                                    _logger.Information($"Mensagem '{message.Id}' commitada.");

                                    //consumer.Pause(topicPartitions);
                                    //_logger.Information($"Consumer paused. {cr.TopicPartition.Topic} / {cr.TopicPartition.Partition}");

                                    //await Task.Delay(TimeSpan.FromSeconds(10));

                                    //consumer.Resume(topicPartitions);
                                    //_logger.Information($"Consumer resumed. {cr.TopicPartition.Topic} / {cr.TopicPartition.Partition}");
                                }
                            }
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        consumer.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.Error($"Erro: {ex.Message}");
            }
        }
        public void Consumer_Pause_Resume(string bootstrapServers)
        {
            LogToFile("start Consumer_Pause_Resume");

            var consumerConfig = new ConsumerConfig
            {
                GroupId          = Guid.NewGuid().ToString(),
                BootstrapServers = bootstrapServers,
                AutoOffsetReset  = AutoOffsetReset.Latest
            };

            var producerConfig = new ProducerConfig {
                BootstrapServers = bootstrapServers
            };

            IEnumerable <TopicPartition> assignment = null;

            using (var topic = new TemporaryTopic(bootstrapServers, 1))
                using (var producer = new ProducerBuilder <byte[], byte[]>(producerConfig).Build())
                    using (var consumer =
                               new ConsumerBuilder <byte[], byte[]>(consumerConfig)
                               .SetPartitionsAssignedHandler((c, partitions) => { assignment = partitions; })
                               .Build())
                    {
                        consumer.Subscribe(topic.Name);

                        while (assignment == null)
                        {
                            consumer.Consume(TimeSpan.FromSeconds(2));
                        }

                        ConsumeResult <byte[], byte[]> record = consumer.Consume(TimeSpan.FromSeconds(2));
                        Assert.Null(record);

                        producer.ProduceAsync(topic.Name, new Message <byte[], byte[]> {
                            Value = Serializers.Utf8.Serialize("test value", SerializationContext.Empty)
                        }).Wait();
                        record = consumer.Consume(TimeSpan.FromSeconds(10));
                        Assert.NotNull(record?.Message);
                        Assert.Equal(0, record?.Offset);

                        consumer.Pause(assignment);
                        producer.ProduceAsync(topic.Name, new Message <byte[], byte[]> {
                            Value = Serializers.Utf8.Serialize("test value 2", SerializationContext.Empty)
                        }).Wait();
                        record = consumer.Consume(TimeSpan.FromSeconds(2));
                        Assert.Null(record);
                        consumer.Resume(assignment);
                        record = consumer.Consume(TimeSpan.FromSeconds(10));
                        Assert.NotNull(record?.Message);
                        Assert.Equal(1, record?.Offset);

                        // check that these don't throw.
                        consumer.Pause(new List <TopicPartition>());
                        consumer.Resume(new List <TopicPartition>());

                        consumer.Close();
                    }

            Assert.Equal(0, Library.HandleCount);
            LogToFile("end   Consumer_Pause_Resume");
        }
        public static void Consumer_Pause_Resume(string bootstrapServers, string singlePartitionTopic, string partitionedTopic)
        {
            LogToFile("start Consumer_Pause_Resume");

            var consumerConfig = new ConsumerConfig
            {
                GroupId          = Guid.NewGuid().ToString(),
                BootstrapServers = bootstrapServers,
                AutoOffsetReset  = AutoOffsetReset.Latest
            };

            var producerConfig = new ProducerConfig {
                BootstrapServers = bootstrapServers
            };

            IEnumerable <TopicPartition> assignment = null;

            using (var producer = new ProducerBuilder <byte[], byte[]>(producerConfig).Build())
                using (var consumer =
                           new ConsumerBuilder <byte[], byte[]>(consumerConfig)
                           .SetRebalanceHandler((c, e) =>
                {
                    if (e.IsAssignment)
                    {
                        c.Assign(e.Partitions);
                        assignment = e.Partitions;
                    }
                })
                           .Build())
                {
                    consumer.Subscribe(singlePartitionTopic);

                    while (assignment == null)
                    {
                        consumer.Consume(TimeSpan.FromSeconds(10));
                    }

                    ConsumeResult <byte[], byte[]> record = consumer.Consume(TimeSpan.FromSeconds(10));
                    Assert.Null(record);

                    producer.ProduceAsync(singlePartitionTopic, new Message <byte[], byte[]> {
                        Value = Serializers.Utf8.Serialize("test value", true, null, null)
                    }).Wait();
                    record = consumer.Consume(TimeSpan.FromSeconds(10));
                    Assert.NotNull(record?.Message);

                    consumer.Pause(assignment);
                    producer.ProduceAsync(singlePartitionTopic, new Message <byte[], byte[]> {
                        Value = Serializers.Utf8.Serialize("test value 2", true, null, null)
                    }).Wait();
                    record = consumer.Consume(TimeSpan.FromSeconds(10));
                    Assert.Null(record);
                    consumer.Resume(assignment);
                    record = consumer.Consume(TimeSpan.FromSeconds(10));
                    Assert.NotNull(record?.Message);

                    // check that these don't throw.
                    consumer.Pause(new List <TopicPartition>());
                    consumer.Resume(new List <TopicPartition>());

                    consumer.Close();
                }

            Assert.Equal(0, Library.HandleCount);
            LogToFile("end   Consumer_Pause_Resume");
        }