Documentation
¶
Overview ¶
Package event provides small CQRS, event sourcing, and message-bus abstractions for Go services.
Index ¶
- Constants
- Variables
- func Ask[R any](ctx context.Context, dispatcher Dispatcher, query Query[R]) (R, error)
- func Execute[A ESAggregate](ctx context.Context, store Store, newAggregate func() A, ...) error
- func HandleCommand[T Command](b *Bus, handler func(context.Context, T) error, opts ...HandlerOption)
- func HandleEvent[T Event](b *Bus, handler func(context.Context, T) error, opts ...HandlerOption)
- func HandleQuery[T Command, R any](b *Bus, handler func(context.Context, T) (R, error))
- func HandleQueueEvent[T Event](b *Bus, handler func(context.Context, T) error, opts ...HandlerOption)
- func MustRegisterMessageType[T any](target TypeRegistry)
- func RegisterMessageType[T any](target TypeRegistry) error
- func ValidateToken(label, token string) error
- func WithMessageMetadata(ctx context.Context, metadata MessageMetadata) context.Context
- type AggregateKey
- type AggregateRef
- type Bus
- func (b *Bus) Connect(ctx context.Context) error
- func (b *Bus) Disconnect() error
- func (b *Bus) DispatchCommand(ctx context.Context, cmd Command) error
- func (b *Bus) DispatchQuery(ctx context.Context, query Command, result any) error
- func (b *Bus) Done() <-chan error
- func (b *Bus) Publish(ctx context.Context, events ...Event) error
- func (b *Bus) RegisterMessageType(prototype any) error
- type BusOptions
- type Command
- type CommandHandler
- type CommandHandlerFunc
- type CommandSubscriber
- type CommandSubscriptionConfig
- type ConflictError
- type CursorBootPolicy
- type CursorStore
- type DecoderRegistry
- type Dispatcher
- type ESAggregate
- type Event
- type EventHandler
- type EventHandlerFunc
- type EventSubscriber
- type EventSubscriptionConfig
- type EventSubscriptionFilter
- type ExecuteConfig
- type ExecuteOption
- type GenericEvent
- type HandlerOption
- type MemoryCursorStore
- type MessageKind
- type MessageKindOverride
- type MessageMetadata
- type Publisher
- type Query
- type QueryHandler
- type QueryHandlerFunc
- type ReadOptions
- type Reader
- type ResponseError
- type SnapshotEvent
- type SnapshotEventBase
- type Snapshottable
- type Store
- type StoredEvent
- type Subject
- type Subscription
- type SubscriptionError
- type SubscriptionFunc
- type TypeRegistry
- type UnknownCommandError
- type UnknownEventError
Constants ¶
const DefaultSnapshotEventName = "snapshot"
Variables ¶
var ( ErrConflict = errors.New("event version conflict") ErrNoResponders = errors.New("no responders available") ErrInvalidResultType = errors.New("invalid query result type") ErrClosed = errors.New("bus is closed") )
var ErrInvalidName = errors.New("invalid message name")
Functions ¶
func Execute ¶
func Execute[A ESAggregate]( ctx context.Context, store Store, newAggregate func() A, mutate func(context.Context, A, uint64, uint64) ([]Event, error), opts ...ExecuteOption, ) error
Execute loads a fresh aggregate, runs mutate, and saves the produced events with optimistic concurrency. newAggregate is called for every retry so a failed attempt never leaks partially applied state into the next attempt.
func HandleCommand ¶
func HandleCommand[T Command](b *Bus, handler func(context.Context, T) error, opts ...HandlerOption)
HandleCommand registers a command handler for T. It must be called before Connect; it panics if the bus is already connected or closed, or if T cannot be registered as a message type.
func HandleEvent ¶
HandleEvent registers an ordered event handler for T. It must be called before Connect; it panics if the bus is already connected or closed, or if T cannot be registered as a message type.
func HandleQuery ¶
HandleQuery registers a query handler for T. It must be called before Connect; it panics if the bus is already connected or closed, or if T cannot be registered as a message type.
func HandleQueueEvent ¶
func HandleQueueEvent[T Event](b *Bus, handler func(context.Context, T) error, opts ...HandlerOption)
HandleQueueEvent registers a queue event handler for T. It must be called before Connect; it panics if the bus is already connected or closed, if T cannot be registered as a message type, or if the bus has no queue configured.
func MustRegisterMessageType ¶
func MustRegisterMessageType[T any](target TypeRegistry)
func RegisterMessageType ¶
func RegisterMessageType[T any](target TypeRegistry) error
func ValidateToken ¶
ValidateToken checks one concrete subject token. Wildcards are intentionally rejected here; subscription filters use separate helpers in transport packages.
func WithMessageMetadata ¶
func WithMessageMetadata(ctx context.Context, metadata MessageMetadata) context.Context
Types ¶
type AggregateKey ¶
AggregateKey is a concrete aggregate reference for callers that only need to identify an aggregate, not replay its state.
func (AggregateKey) AggregateID ¶
func (k AggregateKey) AggregateID() string
func (AggregateKey) AggregateScope ¶
func (k AggregateKey) AggregateScope() string
func (AggregateKey) AggregateType ¶
func (k AggregateKey) AggregateType() string
type AggregateRef ¶
AggregateRef identifies one aggregate instance. "Ref" means reference: these methods name the aggregate without carrying its event-sourced state or behavior.
type Bus ¶
type Bus struct {
// contains filtered or unexported fields
}
func NewBus ¶
func NewBus(dispatcher Dispatcher, publisher Publisher, commands CommandSubscriber, events EventSubscriber, opts BusOptions) *Bus
func (*Bus) Disconnect ¶
func (*Bus) DispatchQuery ¶
func (*Bus) RegisterMessageType ¶
type BusOptions ¶
type BusOptions struct {
Queue string
QueueMaxRetries int
Logger *slog.Logger
CursorStore CursorStore
CursorBootPolicy CursorBootPolicy
OnSubscriptionError func(*SubscriptionError) bool
CommandConflictRetries int
ExcludeCommandDebugNames map[string]bool
}
type Command ¶
type Command interface {
AggregateRef
CommandName() string
}
Command describes an action requested against one aggregate instance.
type CommandHandler ¶
type CommandHandlerFunc ¶
func (CommandHandlerFunc) HandleCommand ¶
func (f CommandHandlerFunc) HandleCommand(ctx context.Context, cmd Command) error
type CommandSubscriber ¶
type CommandSubscriber interface {
SubscribeCommand(context.Context, CommandHandler, CommandSubscriptionConfig) (Subscription, error)
SubscribeQuery(context.Context, QueryHandler, CommandSubscriptionConfig) (Subscription, error)
}
type CommandSubscriptionConfig ¶
type CommandSubscriptionConfig struct {
AggregateScope string
Kind MessageKind
AggregateTypes []string
AggregateIDs []string
CommandNames []string
Queue string
}
func (CommandSubscriptionConfig) Validate ¶
func (c CommandSubscriptionConfig) Validate() error
type ConflictError ¶
func (*ConflictError) Error ¶
func (e *ConflictError) Error() string
func (*ConflictError) Is ¶
func (e *ConflictError) Is(target error) bool
type CursorBootPolicy ¶
type CursorBootPolicy int
const ( CursorBootNew CursorBootPolicy = iota CursorBootAll )
type CursorStore ¶
type DecoderRegistry ¶
type DecoderRegistry interface {
TypeRegistry
NewEvent(kind MessageKind, scope, aggregateType, name string) (Event, error)
DecodeEvent(Subject, []byte) (Event, error)
NewCommand(kind MessageKind, scope, aggregateType, name string) (Command, error)
DecodeCommand(Subject, []byte) (Command, error)
}
func NewTypeRegistry ¶
func NewTypeRegistry() DecoderRegistry
type Dispatcher ¶
type ESAggregate ¶
type ESAggregate interface {
AggregateRef
EventTypes() ([]Event, SnapshotEvent)
Apply(Event)
}
ESAggregate is an event-sourced entity that can rebuild its state from events.
type Event ¶
type Event interface {
AggregateRef
EventName() string
}
Event describes a committed state change for one aggregate instance.
type EventHandler ¶
type EventHandlerFunc ¶
func (EventHandlerFunc) HandleEvent ¶
type EventSubscriber ¶
type EventSubscriber interface {
SubscribeEvents(context.Context, EventHandler, EventSubscriptionConfig) (Subscription, error)
}
type EventSubscriptionConfig ¶
type EventSubscriptionConfig struct {
AggregateScope string
Kind MessageKind
AggregateTypes []string
AggregateIDs []string
EventNames []string
EventFilters []EventSubscriptionFilter
Queue string
ConsumerName string
MaxRetries int
Cursor []byte
CursorBootPolicy CursorBootPolicy
CaughtUp func()
OnError func(*SubscriptionError) bool
}
func (EventSubscriptionConfig) Validate ¶
func (c EventSubscriptionConfig) Validate() error
type EventSubscriptionFilter ¶
type EventSubscriptionFilter struct {
Kind MessageKind
AggregateIDs []string
EventNames []string
}
type ExecuteConfig ¶
type ExecuteOption ¶
type ExecuteOption func(*ExecuteConfig)
func WithExecuteBackoff ¶
func WithExecuteBackoff(baseDelay, maxDelay time.Duration) ExecuteOption
func WithExecuteMaxAttempts ¶
func WithExecuteMaxAttempts(n int) ExecuteOption
type GenericEvent ¶
type GenericEvent struct {
Subject Subject
}
GenericEvent identifies a stored event when the caller did not provide an event-sourced aggregate with concrete event types.
func (GenericEvent) AggregateID ¶
func (e GenericEvent) AggregateID() string
func (GenericEvent) AggregateScope ¶
func (e GenericEvent) AggregateScope() string
func (GenericEvent) AggregateType ¶
func (e GenericEvent) AggregateType() string
func (GenericEvent) EventName ¶
func (e GenericEvent) EventName() string
type HandlerOption ¶
type HandlerOption func(*handlerOptions)
func WithAggregateIDs ¶
func WithAggregateIDs(ids ...string) HandlerOption
type MemoryCursorStore ¶
type MemoryCursorStore struct {
// contains filtered or unexported fields
}
func NewMemoryCursorStore ¶
func NewMemoryCursorStore() *MemoryCursorStore
func (*MemoryCursorStore) LoadCursor ¶
func (*MemoryCursorStore) SaveCursor ¶
type MessageKind ¶
type MessageKind string
const ( KindEvent MessageKind = "event" KindCommand MessageKind = "command" KindQuery MessageKind = "query" )
type MessageKindOverride ¶
type MessageKindOverride interface {
MessageKind() string
}
MessageKindOverride optionally overrides the default kind token used for a message. Empty values are ignored and the call site default is used.
type MessageMetadata ¶
func MessageMetadataFromContext ¶
func MessageMetadataFromContext(ctx context.Context) (MessageMetadata, bool)
type Query ¶
Query describes a read-only request. ResultType is only used for generic type inference and should return the zero value of R.
type QueryHandler ¶
type QueryHandlerFunc ¶
func (QueryHandlerFunc) HandleQuery ¶
type ReadOptions ¶
type ReadOptions struct {
// SkipSnapshotFastPath disables Load-style "start after latest snapshot"
// optimization for event-sourced aggregates. When false (default), typed
// Stream calls start at snapshotSeq+1.
SkipSnapshotFastPath bool
// IncludeSnapshots controls whether snapshot subject messages are yielded
// for event-sourced aggregates. Default false: domain events only.
IncludeSnapshots bool
}
ReadOptions configures aggregate event streaming.
type Reader ¶
type Reader interface {
Stream(ctx context.Context, ref AggregateRef, opts ReadOptions) iter.Seq2[StoredEvent, error]
}
Reader streams aggregate history without mutating aggregate state. If ref also implements ESAggregate, events are decoded into the concrete EventTypes. Plain AggregateRef values stream generic events with opaque Data bytes.
type ResponseError ¶
type ResponseError json.RawMessage
ResponseError represents a structured error received in a CQRS response. It contains the raw JSON payload which can be interpreted by higher layers.
func (ResponseError) Error ¶
func (e ResponseError) Error() string
Error implements the error interface.
func (ResponseError) MarshalJSON ¶
func (e ResponseError) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler, allowing the error to be re-serialized.
func (ResponseError) UnmarshalInto ¶
func (e ResponseError) UnmarshalInto(v any) error
UnmarshalInto allows callers to extract the underlying JSON into a typed struct.
type SnapshotEvent ¶
type SnapshotEvent interface {
Event
SnapshotEvent()
}
type SnapshotEventBase ¶
type SnapshotEventBase struct{}
func (SnapshotEventBase) EventName ¶
func (SnapshotEventBase) EventName() string
func (SnapshotEventBase) SnapshotEvent ¶
func (SnapshotEventBase) SnapshotEvent()
type Snapshottable ¶
type Snapshottable interface {
ESAggregate
TakeSnapshot() (SnapshotEvent, error)
}
Snapshottable aggregates can provide an explicit snapshot event.
type Store ¶
type Store interface {
Save(ctx context.Context, ref AggregateRef, expectedVersion uint64, events ...Event) error
Load(ctx context.Context, agg ESAggregate) (version uint64, err error)
}
Store appends and loads aggregate event streams.
type StoredEvent ¶
type StoredEvent struct {
Event Event
Subject Subject
Data []byte
Version uint64 // store sequence for this message
Timestamp time.Time
}
StoredEvent is one aggregate message read from the event store.
func Collect ¶
func Collect(ctx context.Context, r Reader, ref AggregateRef, opts ReadOptions) ([]StoredEvent, error)
Collect reads all events from a stream into a slice.
func FindFirst ¶
func FindFirst(ctx context.Context, r Reader, ref AggregateRef, opts ReadOptions, pred func(Event) bool) (StoredEvent, bool, error)
FindFirst returns the first stored event matching pred.
type Subject ¶
type Subject struct {
Scope string
Kind MessageKind
AggregateType string
AggregateID string
Name string
}
Subject is the transport-neutral delivery subject of a command, query, or event.
func CommandSubject ¶
func EventSubject ¶
func QuerySubject ¶
type Subscription ¶
type Subscription interface {
Stop() error
}
type SubscriptionError ¶
type SubscriptionError struct {
Subject Subject
Queue string
NumDelivered uint64
RetriesExhausted bool
Transport bool
Err error
}
func (*SubscriptionError) Error ¶
func (e *SubscriptionError) Error() string
func (*SubscriptionError) Unwrap ¶
func (e *SubscriptionError) Unwrap() error
type SubscriptionFunc ¶
type SubscriptionFunc func() error
func (SubscriptionFunc) Stop ¶
func (f SubscriptionFunc) Stop() error
type TypeRegistry ¶
TypeRegistry is the public typed-registration target implemented by Bus and transport adapters that need to decode stored or incoming messages.
type UnknownCommandError ¶
func (*UnknownCommandError) Error ¶
func (e *UnknownCommandError) Error() string
func (*UnknownCommandError) Is ¶
func (e *UnknownCommandError) Is(target error) bool
type UnknownEventError ¶
func (*UnknownEventError) Error ¶
func (e *UnknownEventError) Error() string
func (*UnknownEventError) Is ¶
func (e *UnknownEventError) Is(target error) bool