snapshot of https://github.com/ThreeDotsLabs/watermill.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
master / ci (push) Failing after 0s
Some checks failed
master / ci (push) Failing after 0s
This commit is contained in:
146
components/cqrs/event_bus.go
Normal file
146
components/cqrs/event_bus.go
Normal file
@@ -0,0 +1,146 @@
|
||||
package cqrs
|
||||
|
||||
import (
|
||||
"context"
|
||||
stdErrors "errors"
|
||||
|
||||
"github.com/ThreeDotsLabs/watermill"
|
||||
"github.com/ThreeDotsLabs/watermill/message"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type EventBusConfig struct {
|
||||
// GeneratePublishTopic is used to generate topic name for publishing event.
|
||||
GeneratePublishTopic GenerateEventPublishTopicFn
|
||||
|
||||
// OnPublish is called before sending the event.
|
||||
// The *message.Message can be modified.
|
||||
//
|
||||
// This option is not required.
|
||||
OnPublish OnEventSendFn
|
||||
|
||||
// Marshaler is used to marshal and unmarshal events.
|
||||
// It is required.
|
||||
Marshaler CommandEventMarshaler
|
||||
|
||||
// Logger instance used to log.
|
||||
// If not provided, watermill.NopLogger is used.
|
||||
Logger watermill.LoggerAdapter
|
||||
}
|
||||
|
||||
func (c *EventBusConfig) setDefaults() {
|
||||
if c.Logger == nil {
|
||||
c.Logger = watermill.NopLogger{}
|
||||
}
|
||||
}
|
||||
|
||||
func (c EventBusConfig) Validate() error {
|
||||
var err error
|
||||
|
||||
if c.Marshaler == nil {
|
||||
err = stdErrors.Join(err, errors.New("missing Marshaler"))
|
||||
}
|
||||
|
||||
if c.GeneratePublishTopic == nil {
|
||||
err = stdErrors.Join(err, errors.New("missing GenerateHandlerTopic"))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
type GenerateEventPublishTopicFn func(GenerateEventPublishTopicParams) (string, error)
|
||||
|
||||
type GenerateEventPublishTopicParams struct {
|
||||
EventName string
|
||||
Event any
|
||||
}
|
||||
|
||||
type OnEventSendFn func(params OnEventSendParams) error
|
||||
|
||||
type OnEventSendParams struct {
|
||||
EventName string
|
||||
Event any
|
||||
|
||||
// Message is never nil and can be modified.
|
||||
Message *message.Message
|
||||
}
|
||||
|
||||
// EventBus transports events to event handlers.
|
||||
type EventBus struct {
|
||||
publisher message.Publisher
|
||||
config EventBusConfig
|
||||
}
|
||||
|
||||
// NewEventBus creates a new CommandBus.
|
||||
// Deprecated: use NewEventBusWithConfig instead.
|
||||
func NewEventBus(
|
||||
publisher message.Publisher,
|
||||
generateTopic func(eventName string) string,
|
||||
marshaler CommandEventMarshaler,
|
||||
) (*EventBus, error) {
|
||||
if publisher == nil {
|
||||
return nil, errors.New("missing publisher")
|
||||
}
|
||||
if generateTopic == nil {
|
||||
return nil, errors.New("missing generateTopic")
|
||||
}
|
||||
if marshaler == nil {
|
||||
return nil, errors.New("missing marshaler")
|
||||
}
|
||||
|
||||
return &EventBus{
|
||||
publisher: publisher,
|
||||
config: EventBusConfig{
|
||||
GeneratePublishTopic: func(params GenerateEventPublishTopicParams) (string, error) {
|
||||
return generateTopic(params.EventName), nil
|
||||
},
|
||||
Marshaler: marshaler,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewEventBusWithConfig creates a new EventBus.
|
||||
func NewEventBusWithConfig(publisher message.Publisher, config EventBusConfig) (*EventBus, error) {
|
||||
if publisher == nil {
|
||||
return nil, errors.New("missing publisher")
|
||||
}
|
||||
|
||||
config.setDefaults()
|
||||
if err := config.Validate(); err != nil {
|
||||
return nil, errors.Wrap(err, "invalid config")
|
||||
}
|
||||
|
||||
return &EventBus{publisher, config}, nil
|
||||
}
|
||||
|
||||
// Publish sends event to the event bus.
|
||||
func (c EventBus) Publish(ctx context.Context, event any) error {
|
||||
msg, err := c.config.Marshaler.Marshal(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
eventName := c.config.Marshaler.Name(event)
|
||||
topicName, err := c.config.GeneratePublishTopic(GenerateEventPublishTopicParams{
|
||||
EventName: eventName,
|
||||
Event: event,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "cannot generate topic")
|
||||
}
|
||||
|
||||
msg.SetContext(ctx)
|
||||
|
||||
if c.config.OnPublish != nil {
|
||||
err := c.config.OnPublish(OnEventSendParams{
|
||||
EventName: eventName,
|
||||
Event: event,
|
||||
Message: msg,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "cannot execute OnPublish")
|
||||
}
|
||||
}
|
||||
|
||||
return c.publisher.Publish(topicName, msg)
|
||||
}
|
||||
Reference in New Issue
Block a user