@SagaEventHandler
In the previous chapter, we explored SagaState
, the foundation for managing a saga's state. This chapter dives into @SagaEventHandler
, a crucial annotation for defining methods that react to events within a saga instance.
Understanding @SagaEventHandler
@SagaEventHandler
The @SagaEventHandler
annotation marks methods inside a saga class that handle specific events. These methods become event listeners, responding to relevant domain events published within the system.
Here's a breakdown of the key aspects of @SagaEventHandler
:
Event Listeners: Methods annotated with
@SagaEventHandler
act as event listeners for the saga instance. They are invoked whenever a matching event is published.State Management: Sagas leverage
@SagaEventHandler
methods to process events, update their state (SagaState
), and potentially trigger actions based on the event data and current saga state.init
(Optional): This boolean flag indicates whether the method is an initialization handler. When set totrue
(default isfalse
), the method is called when the saga is first created in response to a starting event.associationProperty
(Mandatory): This attribute specifies the name of the property within the handled event that should be used to associate the event with a saga instance. The saga framework uses this property to link incoming events with the appropriate saga instances.
Optional Retry Functionality:
public int retry() default -1;
: This attribute empowers you to define the number of retries the framework should attempt if an exception occurs while executing the event handler. By default, the retry count is set to-1
, indicating no specific limit on retries.public int retryDelay() default 1000;
: This attribute allows you to specify the delay (in milliseconds) between each retry attempt. The default delay is1000
milliseconds (1 second). These optional features enhance the robustness of your event handling logic by enabling automatic retries in case of transient errors.
Handling Persistent Errors: Dead Event Queues (DEQs)
While retries can help overcome temporary hiccups, there may be situations where event handling consistently fails even after retry attempts. To prevent such events from getting stuck in limbo, the Evento Framework utilizes Dead Event Queues (DEQs).
After exceeding the configured retry limit, the event is automatically routed to a dedicated DLQ.
DLQs act as a safety net, storing these unprocessed events for potential future intervention.
By employing DLQs, Evento ensures efficient processing of most events while providing a mechanism to handle persistent failures and prevent data loss.
Requirements for @SagaEventHandler
Methods
@SagaEventHandler
MethodsThere are two mandatory requirements for methods annotated with @SagaEventHandler
:
First Argument as Event: The first argument of the method must be the type of the event it handles. This allows the method to access the event data for processing.
associationProperty
Setting: You must define theassociationProperty
attribute within the annotation. This property name should correspond to a field within the handled event that uniquely identifies the saga instance the event relates to.
Utilizing SagaState
and Optional Parameters
SagaState
and Optional ParametersSagaState
:@SagaEventHandler
methods can leverage theSagaState
object (often the return type) to manage the saga's state throughout its lifecycle. They might update the state based on the event data and the current saga state.Optional Parameters:
@SagaEventHandler
methods can also receive additional optional parameters:CommandGateway
andQueryGateway
: These gateways allow interacting with the domain by sending commands or executing queries within the saga logic.EventMessage<?>
: Provides access to the entire event message object.Instant
: Offers the timestamp of the event occurrence.Metadata
: Grants access to any metadata associated with the event.
Example: DemoSaga
Event Handlers
DemoSaga
Event HandlersThe provided DemoSaga
class showcases several @SagaEventHandler
methods:
on(DemoCreatedEvent)
: This method is marked withinit=true
, indicating it's the initialization handler for the saga. It creates a newDemoSagaState
, sets the association based on thedemoId
from the event, and returns the state object.on(DemoUpdatedEvent)
: This method handlesDemoUpdatedEvent
. It checks a condition based on the event's value and potentially interacts with the domain using gateways. It updates thelastValue
property in theSagaState
and returns the updated state.on(DemoDeletedEvent)
: This method handlesDemoDeletedEvent
. It retrieves data using theQueryGateway
, sends a notification using theCommandGateway
, and marks theSagaState
as ended.
Note: This example doesn't showcase the optimal usage of sagas for handling eventual consistency concerns.
Key Takeaways
@SagaEventHandler
empowers sagas to react to relevant events and manage their state accordingly.Understanding
@SagaEventHandler
is essential for building robust sagas that coordinate long-running workflows within Evento.Effective use of
SagaState
and optional parameters allows for informed decision-making and potential interactions with the domain within the saga logic.
The next chapter might explore a different saga usage example that highlights eventual consistency concerns and how sagas can handle them.
Last updated