Skip to content

Publish/Subscribe CloudEvents in .NET, inspired by Dapr Pub/Sub

License

Notifications You must be signed in to change notification settings

DCArea/CloudEventDotNet

Repository files navigation

CloudEventDotNet

Publish/Subscribe CloudEvents in .NET, inspired by Dapr Pub/Sub Component

Features

  • Publish/Subscribe events with CloudEvent format
  • With both Kafka and Redis support
  • At-Least-Once delivery guarantee
  • Redeliver failed events
  • Obeservability support (traces/metrics)
  • DOES NOT support delivery events in order

Usage

Install package

dotnet add package CloudEventDotNet
dotnet add package CloudEventDotNet.Redis # With Redis Stream
dotnet add package CloudEventDotNet.Kafka # With Apache Kafka

Configure pubsub:

services.AddCloudEvents(defaultPubSubName: "kafka", defaultTopic: "my-topic")
    .Load(typeof(OrderCancelled).Assembly)
    .AddKafkaPubSub("kafka", options =>
    {
        options.ProducerConfig = new ProducerConfig
        {
            BootstrapServers = broker,
        };
    }, options =>
    {
        options.ConsumerConfig = new ConsumerConfig
        {
            BootstrapServers = broker,
            GroupId = consumerGroup,
        };
    })
    .AddRedisPubSub("redis", options =>
    {
        options.ConnectionMultiplexerFactory = () => redis;
        options.MaxLength = maxLength;
    }, options =>
    {
        options.ConnectionMultiplexerFactory = () => redis;
        options.ConsumerGroup = consumerGroup;
    })
    .AddPubSubDeadLetterSender(opts => // enable dead letter
    {
        opts.Topic = "DL";
    });

Define cloud event:

[CloudEvent] // register event with default pubsub name and topic
public record OrderCancelled(Guid OrderId, string Reason);

Define cloud event with custom metadata

[CloudEvent(PubSubName = "redis", Topic = "another-topic", Type = "a-custom-type")]
public record OrderCancelled(Guid OrderId, string Reason);

Publish a cloud event:

var pubsub = serviceProvider.GetRequiredService<ICloudEventPubSub>();
await pubsub.PublishAsync(new OrderCancelled(order.Id, reason));

Subscribe and process cloud event:

public class OrderCancelledHandler : ICloudEventHandler<OrderCancelled>
{
    public async Task HandleAsync(CloudEvent<PingEvent> cloudEvent, CancellationToken token)
    {
        // ...
    }
}

Performance

The benchmark result on a 4*2.4GHz Core VM:

Kafka Redis
Publish ~100k/s ~90k/s
Subscribe ~150k/s ~40k/s

The benchmark code is located at perf/CloudEventTester