In the system I’m starting to work on we’re having a challenge of events becoming too big. I think the correct approach in general is to try to redesign them and split into smaller ones and try to follow the ideas in the presentation and article “Put your events on a diet”.
But then there’s a feature called databus and I was wondering if you have any good examples of when this is a sensible choice from the design perspective and under what circumstances this would be a better approach than trying to slim down your events?
Welcome, @weralabaj
Usually the DataBus is designed to share big chunks of data, for example, a PDF document or any other kind of byte[].
If events are getting bigger because they sharing too much data then the ideal approach is to reduce their sharing surface and put them on a diet.
However, in an existing system that could cause some headaches, because subscribers are probably relying on that data being shared and their business logic expect them. All that could cause a ripple effect that is had to control. I’d suggest to start with one or two events, and before changing anything investigate why the data they are sharing needs to be shared in the first place. From there, investigate what could be an alternative approach to not sharing, and finally introduce a new event type that doesn’t share data to publish it alongside the old one until all subscribers have been upgraded to the new thin events style.
.m
You use databus when the object can’t be logically made smaller and you are not dealing with BLOB’s.
However, as very often you are dealing with TEXT based serialization its that that is causing the issues which is why I wanted to make you aware of other options too:
- NServiceBus.Attachments by Simon
- Binary serializers like using BJON or ProtoBuf (also by Simon)
- NServiceBus.Compression by Ramon
or a combination of the above!
So why ProtoBuf? Because it more or less is the defacto wire-format due to the wide spread adoption of gRPC.
IMHO the databus is primarily meant for large objects. Yes, you can add BLOB’s in properties too with the databus but when dealing with BLOB’s it is much better to use NServiceBus.Attachments by Simon Cropp
. It acts similarly as how you deal with attachements with email. Especially useful is the attachment itself does not contain primary routing/processing data like most BLOB’s like PDFs, images, movies, etc.
Simon also made a good comparison between DataBus and Attachments:
Read on demand
With the DataBus all binary data is read every message received. This is irrespective of if the receiving endpoint requires that data. With NServiceBus.Attachments data is explicitly read on demand, so if data is not required there is no performance impact. NServiceBus.Attachments also supports processing all data items via an IAsyncEnumerable
.
Memory usage
With the DataBus all data items are placed into byte arrays. This means that memory needs to be allocated to store those arrays on either reading or writing. With NServiceBus.Attachments data can be streamed and processed in an async manner. This can significantly decrease the memory pressure on an endpoint.
Variety of data APIs
With the DataBus the only interaction is via byte arrays. NServiceBus.Attachments supports reading and writing using streams, byte arrays, or string.
Thank you, that was really helpful!