Table of Contents

Kafka - Batch Processing with Tombstones

In this sample the producer publishes batches of messages that include some tombstones (messages with a key but a null value) and the consumer processes them in batch, telling the tombstones apart from the regular messages.

What This Sample Shows

  • Publishing a batch with WrapAndPublishBatchAsync, mapping each source item to a message and returning null (every number divisible by 30) to produce a tombstone.
  • Setting the Kafka key of each envelope (N<number>) so that the tombstones still carry a key.
  • Consuming in batches of up to 100 messages (or whatever is received within 5 seconds) with EnableBatchProcessing.
  • Subscribing to a stream of IInboundEnvelope<SampleMessage> and checking IsTombstone to handle the tombstones, using GetKafkaKey to read the key.

How to Run

Start the infrastructure as described in Samples, then run the two applications from the repository root.

dotnet run --project ./samples/Kafka/BatchWithTombstone.Producer/.
dotnet run --project ./samples/Kafka/BatchWithTombstone.Consumer/.

The consumer logs every received message or tombstone together with its key and then the size of each processed batch.

Common

The message being exchanged is defined in a common project.

namespace Silverback.Samples.Kafka.BatchWithTombstone.Common;

public class SampleMessage
{
    public int Number { get; set; }
}

Full source code: https://github.com/BEagle1984/silverback/tree/master/samples/Kafka/BatchWithTombstone.Common

Producer

The producer uses a hosted service to publish batches of 100 messages in the background, replacing some of them with tombstones.

using Microsoft.Extensions.DependencyInjection;
using Silverback.Configuration;
using Silverback.Messaging.Configuration;

namespace Silverback.Samples.Kafka.BatchWithTombstone.Producer;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // Enable Silverback
        services.AddSilverback()

            // Use Apache Kafka as message broker
            .WithConnectionToMessageBroker(options => options.AddKafka())

            // Delegate the broker clients configuration to a separate class
            .AddBrokerClientsConfigurator<BrokerClientsConfigurator>();

        // Add the hosted service that produces the random sample messages
        services.AddHostedService<ProducerBackgroundService>();
    }

    public void Configure()
    {
    }
}

Full source code: https://github.com/BEagle1984/silverback/tree/master/samples/Kafka/BatchWithTombstone.Producer

Consumer

The consumer processes the messages in batch, logging the key of each tombstone and the key and number of each regular message.

using Microsoft.Extensions.DependencyInjection;
using Silverback.Configuration;
using Silverback.Messaging.Configuration;

namespace Silverback.Samples.Kafka.BatchWithTombstone.Consumer;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // Enable Silverback
        services.AddSilverback()

            // Use Apache Kafka as message broker
            .WithConnectionToMessageBroker(options => options.AddKafka())

            // Delegate the broker clients configuration to a separate class
            .AddBrokerClientsConfigurator<BrokerClientsConfigurator>()

            // Register the subscribers
            .AddSingletonSubscriber<SampleMessageBatchSubscriber>();
    }

    public void Configure()
    {
    }
}

Full source code: https://github.com/BEagle1984/silverback/tree/master/samples/Kafka/BatchWithTombstone.Consumer

Additional Resources