Message Bus Dye Test

November 10, 2024

Header Image

In this post, I’d like to discuss the concept of a dye test in a message bus. This concept is applicable to any message bus, but here we’ll specifically be using ASB.

It’s nowhere near finished, but this project might help you get started if you decide you’d like to attempt something similar.

Dye test

Dye tests are used in real life scenarios from detecting water contamination to medical diagnostics. The idea is the same - put something into a system that you can detect and see where it goes.

Stream

The exact same scenario is true for a distributed system. It’s not always obvious where your message may be received within the wider system, and so you can detect that by feeding a message into the system with a correlation ID, and then looking at all the subscriptions within your system to see where that message is received.

Caveats

There is a Heisenberg factor here - many message brokers track when you “receive” a message - if you don’t consume it, they flag that you’ve tried to read it. This means that you run an, albeit small, risk of dead-lettering valid messages while running your test.

How?

Here’s the relevant top level code:

var message = new
{
    Message = "Dye Test",
    DateTime = DateTime.Now               
};

var messageBody = System.Text.Json.JsonSerializer.Serialize(message);
_track.Configure(messageBody);

int count = await _track.Inject();
await Task.Delay(5000);
var traces = await _track.Detect();

Essentially, post a message to a topic or, in this case, all topics:

foreach (var topic in topics)
{
    var correlationId = Guid.NewGuid().ToString();
    await _send.SendWithCorrelationId(correlationId,
        topic, _message);

Then, when reading, check every subscription for every topic:

foreach (var trace in _traces)
{
    var subscriptions = await _management.GetAllSubscriptions(trace.Topic);

    foreach (var subscription in subscriptions)
    {        
        if (await _receive.ReceiveCorrelationId(
            trace.CorrelationId, trace.Topic, subscription))

The output will look something like this:

Message Miner Output

Conclusion

There are ways to manage the flow of your messages, and so resorting to this kind of approach is probably a sign that you need tighter governance over who listens to the messages and how. However, it can also save you from crashing a downstream system that you weren’t aware of.



Profile picture

A blog about one man's journey through code… and some pictures of the Peak District
Twitter

© Paul Michaels 2024