EventBus publish

We’ve run into a situation where multiple threads are publishing events for the same aggregate into the EventBus.

This has caused a bit of a problem where one UnitOfWork can contain multiple events (E1, E2, E3), and at the same time, another thread publishes an event for the same aggregate (E10).

Ideally I would like: E1, E2, E3, E10 - but instead we get (as an example) E1, E10, E2, E3.

We’re using the DisruptorCommandBus, is it safe to assume that calls to EventBusTerminal’s publish() will always contain at least all the events for one UnitOfWork?

If so, I think I should be able to put a simple semaphore around the cluster.publish() loop when there is more than one EventMessage?

JAmes

Hi James,

as far as I can tell, this can only occur if the thread that publishes E10 doesn’t use the same DisruptorCommandBus instance as the publication of E1-3. Because the DisruptorCommand bus will ensure publication of the events in the correct order (for a single aggregate, at least).

Currently, all UoW implementations will publish all registered events in a single call to EventBus.publish(), which does a single call to EventBusTerminal.publish().

Before implementing the semaphore, please double check the routing of your command. Semaphores involve serialization (of execution, not the byte writing stuff), meaning that Amdahl will come and hunt you down…

Cheers,

Allard

Hi James,

as far as I can tell, this can only occur if the thread that publishes E10 doesn’t use the same DisruptorCommandBus instance as the publication of E1-3. Because the DisruptorCommand bus will ensure publication of the events in the correct order (for a single aggregate, at least).

I’ve been digging through the code and I think I left out an important detail; it’s an @EventHandler that runs after the event has been persisted in an EventStore that is publishing E10, directly onto the EventBus.

So if E10 is published to the event bus as a result of handling E1, I think it’s possible (though unlikely), that E10 could be queued up in the EventBus before E2 and E3 make it?

Currently, all UoW implementations will publish all registered events in a single call to EventBus.publish(), which does a single call to EventBusTerminal.publish().

SimpleEventBusTerminal publishes to AsynchronousCluster which calls schedule(event); in a loop, which is why I believe the interleaved events can occur in my use case?

JAmes

Hi James,

the solution to this is to use the UnitOfWork to schedule the event, instead of publishing it directly. However, in an event handler you cannot assume there is one active.

What you would need to do is:
if (CurrentUnitOfWork.isStarted()) {
CurrentUnitOfWork.get().publishEvent(myEvent, eventBus);
} else {
eventBus.publish(myEvent);
}

This doesn’t deserve the first prize for absolute beauty, I admit. I’ve been playing with a similar concept as the CommandGateway for events. Maybe I should plan that one for the next release.

Cheers,

Allard