Files
upstream-watermill/components/cqrs/event_handler.go
2026-09-15 21:27:46 +05:00

74 lines
2.2 KiB
Go

package cqrs
import (
"context"
)
// EventHandler receives events defined by NewEvent and handles them with its Handle method.
// If using DDD, CommandHandler may modify and persist the aggregate.
// It can also invoke a process manager, a saga or just build a read model.
//
// In contrast to CommandHandler, every Event can have multiple EventHandlers.
//
// One instance of EventHandler is used during handling messages.
// When multiple events are delivered at the same time, Handle method can be executed multiple times at the same time.
// Because of that, Handle method needs to be thread safe!
type EventHandler interface {
// HandlerName is the name used in message.Router while creating handler.
//
// It will be also passed to EventsSubscriberConstructor.
// May be useful, for example, to create a consumer group per each handler.
//
// WARNING: If HandlerName was changed and is used for generating consumer groups,
// it may result with **reconsuming all messages** !!!
HandlerName() string
NewEvent() any
Handle(ctx context.Context, event any) error
}
type genericEventHandler[T any] struct {
handleFunc func(ctx context.Context, event *T) error
handlerName string
}
// NewEventHandler creates a new EventHandler implementation based on provided function
// and event type inferred from function argument.
func NewEventHandler[T any](
handlerName string,
handleFunc func(ctx context.Context, event *T) error,
) EventHandler {
return &genericEventHandler[T]{
handleFunc: handleFunc,
handlerName: handlerName,
}
}
func (c genericEventHandler[T]) HandlerName() string {
return c.handlerName
}
func (c genericEventHandler[T]) NewEvent() any {
tVar := new(T)
return tVar
}
func (c genericEventHandler[T]) Handle(ctx context.Context, e any) error {
event := e.(*T)
return c.handleFunc(ctx, event)
}
type GroupEventHandler interface {
NewEvent() interface{}
Handle(ctx context.Context, event interface{}) error
}
// NewGroupEventHandler creates a new GroupEventHandler implementation based on provided function
// and event type inferred from function argument.
func NewGroupEventHandler[T any](handleFunc func(ctx context.Context, event *T) error) GroupEventHandler {
return &genericEventHandler[T]{
handleFunc: handleFunc,
}
}