Skip to content

Expose events on published and consumed #84

Description

This would enable us to run custom code on all events without having to implement it in every handler.

Our problem

We want to get custom metrics on each published/consumed event. We currently do this by having a method call in every handler.
In this event we need to have access to these properties:

  • Topic
  • Classname of the event

Our current solution (this does not give us topic)

 public async Task Handle(DepartureScheduled message, MessageHandlerContext context)
 {
     CustomMetric.Consume(message);
     var existingDeparture = await _departureRepository.GetDepartureAsync(message.DepartureId);
     if (existingDeparture == null)
         await _departureRepository.CreateDepartureAsync(new Departure(message);
 }

Proposed solution

Instead of having to call this method in every handler we could make a static event in dafda when a message is handled/published
Here is a draft on what it could look like

public static class DafdaProducerEvents
{
    public static event EventHandler<PublishedEventArgs> MessagePublished;
    public static void OnMessagePublished(string topic, string key, string value)
    {
        MessagePublished?.Invoke(null, new PublishedEventArgs(topic, key, value));
    }
    public class PublishedEventArgs(string Topic, string Key, string Value) : EventArgs
    {
        public string Topic { get; } = Topic;
        public string Key { get; } = Key;
        public string Value { get; } = Value;
    }
}

KafkaProducer

public async Task Produce(PayloadDescriptor payloadDescriptor)
{
    if (ShouldPublishInternalEvent)
        DafdaProducerEvents.OnMessagePublished(payloadDescriptor.TopicName, payloadDescriptor.PartitionKey, payloadSerialized);
}
public KafkaProducer(ILoggerFactory loggerFactory, IEnumerable<KeyValuePair<string, string>> configuration, TopicPayloadSerializerRegistry payloadSerializerRegistry)
{
    if (configuration.FirstOrDefault(p => p.Key == "ShouldPublishInternalEvent").Value == "true")
        ShouldPublishInternalEvent = true;
}

Producer options

public void ShouldPublishInternalEvent()
{
    _builder.WithConfiguration("ShouldPublishInternalEvent", "true");
}

I have removed the original dafda logic to make the code easier to read.
This example is only for the KafkaProducer but would have to be added for the other producers aswell as the handlers.
This is just one way to solve the problem, we were also suggested to use opentelemetry, but one problem with that is getting access to the data of the event.

A quick note is that this seems to be a similar request to #5

Metadata

Metadata

Assignees

No one assigned

    Fields

    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions