Publish Subscribe Event Handlers

Ecotone implements Publish Subscribe Event Handlers, which means that each of the Handlers receives it's own copy of a Message in order to handle it atomically.
You may take a look on Asynchronous Handling chapter, to get overview of how asynchronous processing works.


Let's consider scenario, when Order Was Placed, we want send order confirmation and reserve products in Stock via HTTP call.
This could potentially look like this:
#[EventHandler(endpointId: "notifyAboutNewOrder")]
public function notifyAboutNewOrder(OrderWasPlaced $event, NotificationService $notificationService) : void
#[EventHandler(endpointId: "reserveItemsInStock")]
public function reserveItemsInStock(OrderWasPlaced $event, StockClient $stockClient): void
$stockClient->reserve($event->getOrderId(), $event->getProducts());
Now let's imagine that, our Event goes to asynchronous_messages channel (queue), our message is consumed and order confirmation is sent successfully. After sending confirmation we want to reserve items in Stock, however the API call fails. This means that this Event will be replied and we will retry all our handlers once more. Yet this is not what we want, as first Handler was successful, the second needs to be replied only, so let's divine in how Ecotone solves that.

Sending a copy to each of the Handlers

There is a big difference on the fundamental level to how Ecotone's messaging works, comparing to other PHP Messaging Frameworks. In Ecotone each of the Handlers will receive it's own copy of the Event and will handle it in isolation.
In Ecotone retrying Events is safe, as each of the Handlers is handled in isolation.
This means that under the hood, there would be two messages sent to asynchronous_messages each targeting specific Event Handler. This bring safety to retrying events, as we will only retry Handler that actually failed.
As in Ecotone it's the Handler that becomes Asynchronous (not Event itself) you may customize the behaviour to your needs. If you want you may run some Event Handler synchronously and some asynchronously. You may even decide to have different Message Channels defined for each of the Asynchronous Event Handlers.