Add comprehensive documentation for Singularity struct methods
All checks were successful
Go CI/CD / go-ci (push) Successful in 36s

Added detailed comments for struct `singularity`, its methods, and helper functions to improve code clarity and maintainability. This includes explanations of each method's purpose, input/output, and thread-safety mechanisms where applicable.
This commit is contained in:
Rene Nochebuena 2025-04-26 22:33:20 -06:00
parent bc3c5aa846
commit 457ff24dcc
Signed by: Rene Nochebuena
GPG Key ID: A9FD83117EA538D8

View File

@ -8,6 +8,9 @@ import (
"sync" "sync"
) )
// singularity is a type that orchestrates command, query, and event handling.
// It maintains handlers and middlewares for commands, queries, and events.
// A mutex is used for thread-safe access to the handlers and middlewares.
type singularity struct { type singularity struct {
commandHandlers map[string]CommandHandler commandHandlers map[string]CommandHandler
queryHandlers map[string]QueryHandler queryHandlers map[string]QueryHandler
@ -18,6 +21,7 @@ type singularity struct {
mutex sync.RWMutex mutex sync.RWMutex
} }
// NewSingularity initializes and returns a new instance of a Bus.
func NewSingularity() Bus { func NewSingularity() Bus {
return &singularity{ return &singularity{
commandHandlers: make(map[string]CommandHandler), commandHandlers: make(map[string]CommandHandler),
@ -29,6 +33,8 @@ func NewSingularity() Bus {
} }
} }
// RegisterCommandHandler registers a handler for the specified command type.
// It applies any registered CommandMiddleware to the handler.
func (s *singularity) RegisterCommandHandler( func (s *singularity) RegisterCommandHandler(
cmd Command, handler CommandHandler, cmd Command, handler CommandHandler,
) { ) {
@ -40,6 +46,8 @@ func (s *singularity) RegisterCommandHandler(
s.commandHandlers[typeName(cmd)] = handler s.commandHandlers[typeName(cmd)] = handler
} }
// RegisterQueryHandler registers a handler for the specified query type.
// It applies any registered QueryMiddleware to the handler.
func (s *singularity) RegisterQueryHandler(query Query, handler QueryHandler) { func (s *singularity) RegisterQueryHandler(query Query, handler QueryHandler) {
s.mutex.Lock() s.mutex.Lock()
defer s.mutex.Unlock() defer s.mutex.Unlock()
@ -49,6 +57,9 @@ func (s *singularity) RegisterQueryHandler(query Query, handler QueryHandler) {
s.queryHandlers[typeName(query)] = handler s.queryHandlers[typeName(query)] = handler
} }
// RegisterEventHandler registers an event handler for a specific event type.
// It applies any registered EventMiddleware to the handler.
// Handlers are stored in a list, allowing multiple handlers for the same event.
func (s *singularity) RegisterEventHandler(event Event, handler EventHandler) { func (s *singularity) RegisterEventHandler(event Event, handler EventHandler) {
s.mutex.Lock() s.mutex.Lock()
defer s.mutex.Unlock() defer s.mutex.Unlock()
@ -59,18 +70,23 @@ func (s *singularity) RegisterEventHandler(event Event, handler EventHandler) {
s.eventHandlers[name] = append(s.eventHandlers[name], handler) s.eventHandlers[name] = append(s.eventHandlers[name], handler)
} }
// UseCommandMiddleware appends a CommandMiddleware to the middleware chain.
func (s *singularity) UseCommandMiddleware(middleware CommandMiddleware) { func (s *singularity) UseCommandMiddleware(middleware CommandMiddleware) {
s.commandMiddlewares = append(s.commandMiddlewares, middleware) s.commandMiddlewares = append(s.commandMiddlewares, middleware)
} }
// UseQueryMiddleware appends a QueryMiddleware to the middleware chain.
func (s *singularity) UseQueryMiddleware(middleware QueryMiddleware) { func (s *singularity) UseQueryMiddleware(middleware QueryMiddleware) {
s.queryMiddlewares = append(s.queryMiddlewares, middleware) s.queryMiddlewares = append(s.queryMiddlewares, middleware)
} }
// UseEventMiddleware appends a EventMiddleware to the middleware chain.
func (s *singularity) UseEventMiddleware(middleware EventMiddleware) { func (s *singularity) UseEventMiddleware(middleware EventMiddleware) {
s.eventMiddlewares = append(s.eventMiddlewares, middleware) s.eventMiddlewares = append(s.eventMiddlewares, middleware)
} }
// ExecuteCommand processes a command and emits resulting events if any.
// It returns the emitted events or an error if the processing fails.
func (s *singularity) ExecuteCommand(ctx context.Context, cmd Command) ( func (s *singularity) ExecuteCommand(ctx context.Context, cmd Command) (
[]Event, error, []Event, error,
) { ) {
@ -93,6 +109,8 @@ func (s *singularity) ExecuteCommand(ctx context.Context, cmd Command) (
return events, nil return events, nil
} }
// ExecuteQuery executes the given query by invoking its registered handler.
// It returns the result of the query or an error if no handler is found.
func (s *singularity) ExecuteQuery( func (s *singularity) ExecuteQuery(
ctx context.Context, query Query, ctx context.Context, query Query,
) (interface{}, error) { ) (interface{}, error) {
@ -103,6 +121,8 @@ func (s *singularity) ExecuteQuery(
return handler.Handle(ctx, query) return handler.Handle(ctx, query)
} }
// EmitEvent dispatches an event to all registered handlers for its type.
// Returns an error if any handler processing the event fails.
func (s *singularity) EmitEvent(ctx context.Context, event Event) error { func (s *singularity) EmitEvent(ctx context.Context, event Event) error {
handlers := s.getEventHandlers(event) handlers := s.getEventHandlers(event)
if len(handlers) == 0 { if len(handlers) == 0 {
@ -117,6 +137,8 @@ func (s *singularity) EmitEvent(ctx context.Context, event Event) error {
return nil return nil
} }
// emitEvents dispatches multiple events by calling EmitEvent for each one.
// Returns an error if any event fails to emit.
func (s *singularity) emitEvents(ctx context.Context, events ...Event) error { func (s *singularity) emitEvents(ctx context.Context, events ...Event) error {
for _, event := range events { for _, event := range events {
if err := s.EmitEvent(ctx, event); err != nil { if err := s.EmitEvent(ctx, event); err != nil {
@ -126,6 +148,8 @@ func (s *singularity) emitEvents(ctx context.Context, events ...Event) error {
return nil return nil
} }
// getCommandHandler retrieves a command handler for a given command type.
// Returns an error if no handler is registered for the query type.
func (s *singularity) getCommandHandler(cmd Command) (CommandHandler, error) { func (s *singularity) getCommandHandler(cmd Command) (CommandHandler, error) {
s.mutex.RLock() s.mutex.RLock()
defer s.mutex.RUnlock() defer s.mutex.RUnlock()
@ -139,6 +163,8 @@ func (s *singularity) getCommandHandler(cmd Command) (CommandHandler, error) {
return handler, nil return handler, nil
} }
// getQueryHandler retrieves a query handler for a given query type.
// Returns an error if no handler is registered for the query type.
func (s *singularity) getQueryHandler(query Query) (QueryHandler, error) { func (s *singularity) getQueryHandler(query Query) (QueryHandler, error) {
s.mutex.RLock() s.mutex.RLock()
defer s.mutex.RUnlock() defer s.mutex.RUnlock()
@ -151,12 +177,15 @@ func (s *singularity) getQueryHandler(query Query) (QueryHandler, error) {
return handler, nil return handler, nil
} }
// getEventHandlers retrieves all registered event handlers for a given event type.
func (s *singularity) getEventHandlers(event Event) []EventHandler { func (s *singularity) getEventHandlers(event Event) []EventHandler {
s.mutex.RLock() s.mutex.RLock()
defer s.mutex.RUnlock() defer s.mutex.RUnlock()
return s.eventHandlers[typeName(event)] return s.eventHandlers[typeName(event)]
} }
// typeName returns the name of the type of the given value.
// If the value is a pointer, it dereferences the type before returning its name.
func typeName(v interface{}) string { func typeName(v interface{}) string {
t := reflect.TypeOf(v) t := reflect.TypeOf(v)
if t.Kind() == reflect.Ptr { if t.Kind() == reflect.Ptr {
@ -165,6 +194,7 @@ func typeName(v interface{}) string {
return t.Name() return t.Name()
} }
// applyCommandMiddleware applies a chain of middlewares to a CommandHandler.
func applyCommandMiddleware( func applyCommandMiddleware(
handler CommandHandler, middlewares []CommandMiddleware, handler CommandHandler, middlewares []CommandMiddleware,
) CommandHandler { ) CommandHandler {
@ -174,6 +204,7 @@ func applyCommandMiddleware(
return handler return handler
} }
// applyQueryMiddleware applies a chain of middlewares to a QueryHandler.
func applyQueryMiddleware( func applyQueryMiddleware(
handler QueryHandler, middlewares []QueryMiddleware, handler QueryHandler, middlewares []QueryMiddleware,
) QueryHandler { ) QueryHandler {
@ -183,6 +214,7 @@ func applyQueryMiddleware(
return handler return handler
} }
// applyEventMiddleware applies a chain of middleware to an EventHandler.
func applyEventMiddleware( func applyEventMiddleware(
handler EventHandler, middlewares []EventMiddleware, handler EventHandler, middlewares []EventMiddleware,
) EventHandler { ) EventHandler {