Debouncing Events

We’ve adopted to use an event bus in our modular monolith, and have seen a very positive return on that investment (in managing dependencies between packs, and the system capabilities enabled).

However, as we analyze our system behavior at runtime (under real traffic), we’ve observed a situation with which folks here might have experience.

For context, we’re building an Ads platform… to manage the sale of advertising space as well as to manage the delivery of those ads with other vendors.

We have fine grained things (like an Ad) and course grained things (like an Order, containing 1000s of Ads). When 1 Ad changes, an event is fired… then an event handler will execute to update an Order (eg, the total price of an Ad changes, triggering an update in a total price of a pending Order); that will in turn generate an event announcing the Order has updated.

So, Update Ad => Ad Updated Event => Update Order => Order Updated Event

However, when all 1000 ads in an Order change, you can guess what happens: 1000 updates of the order (999 are needless), and 1000 events announcing the Order was updated (999 are needless). Those 999 superfluous events are causing processing delays of other events.

Questions for the community:

  • do you have an event bus in your modular monolith?
  • did you find a need to debounce certain events?
  • does your event bus technology (eg, RabbitMQ) already support this requirement?
  • did you build your own? If so, describe your solution.
1 Like

Yes, yes, no-ish (Kafka no, sidekiq eh), yes

@technicalpickles knows a lot more!

Can I ask what it is about your ads changing that requires the order to change also?

I don’t want to know anything sensitive, but it sounds like there might be one or more data items shared between these two entities (I don’t mean that as a technical term) that might not need to be shared.

For example, I might save both a Customer name and a Customer id in an Order. But I might not change the name in the Order even if the name is later changed in the Customer record. The reason for this could be to preserve the Order history: this was the name of the person that placed the Order. But I can still look up the Customer’s current name using the Customer id in the Order. Of course, there could also be valid reasons to update Customer name in the Order. This is just an example.

It sounds like something common to all the ads is changing in exactly the same way. Is it possible that this piece of information could be kept only in the order (or somewhere else) and changed once there? For example, if the ads all have the same price, could the price live in just in the Order?

If the price must be recorded in both Ad and Order, then maybe the canonical price could be kept somewhere else, like a pricing table, and changes to this entity trigger change events to both Ads and Orders. Again, price is just an example.

I guess what I’m asking is if it would be possible to change the boundaries between these two concepts (and possibly add a third concept) to eliminate this issue.

I hope this is helpful!

2 Likes