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"
)
// 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 {
commandHandlers map[string]CommandHandler
queryHandlers map[string]QueryHandler
@ -18,6 +21,7 @@ type singularity struct {
mutex sync.RWMutex
}
// NewSingularity initializes and returns a new instance of a Bus.
func NewSingularity() Bus {
return &singularity{
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(
cmd Command, handler CommandHandler,
) {
@ -40,6 +46,8 @@ func (s *singularity) RegisterCommandHandler(
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) {
s.mutex.Lock()
defer s.mutex.Unlock()
@ -49,6 +57,9 @@ func (s *singularity) RegisterQueryHandler(query Query, handler QueryHandler) {
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) {
s.mutex.Lock()
defer s.mutex.Unlock()
@ -59,18 +70,23 @@ func (s *singularity) RegisterEventHandler(event Event, handler EventHandler) {
s.eventHandlers[name] = append(s.eventHandlers[name], handler)
}
// UseCommandMiddleware appends a CommandMiddleware to the middleware chain.
func (s *singularity) UseCommandMiddleware(middleware CommandMiddleware) {
s.commandMiddlewares = append(s.commandMiddlewares, middleware)
}
// UseQueryMiddleware appends a QueryMiddleware to the middleware chain.
func (s *singularity) UseQueryMiddleware(middleware QueryMiddleware) {
s.queryMiddlewares = append(s.queryMiddlewares, middleware)
}
// UseEventMiddleware appends a EventMiddleware to the middleware chain.
func (s *singularity) UseEventMiddleware(middleware EventMiddleware) {
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) (
[]Event, error,
) {
@ -93,6 +109,8 @@ func (s *singularity) ExecuteCommand(ctx context.Context, cmd Command) (
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(
ctx context.Context, query Query,
) (interface{}, error) {
@ -103,6 +121,8 @@ func (s *singularity) ExecuteQuery(
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 {
handlers := s.getEventHandlers(event)
if len(handlers) == 0 {
@ -117,6 +137,8 @@ func (s *singularity) EmitEvent(ctx context.Context, event Event) error {
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 {
for _, event := range events {
if err := s.EmitEvent(ctx, event); err != nil {
@ -126,6 +148,8 @@ func (s *singularity) emitEvents(ctx context.Context, events ...Event) error {
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) {
s.mutex.RLock()
defer s.mutex.RUnlock()
@ -139,6 +163,8 @@ func (s *singularity) getCommandHandler(cmd Command) (CommandHandler, error) {
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) {
s.mutex.RLock()
defer s.mutex.RUnlock()
@ -151,12 +177,15 @@ func (s *singularity) getQueryHandler(query Query) (QueryHandler, error) {
return handler, nil
}
// getEventHandlers retrieves all registered event handlers for a given event type.
func (s *singularity) getEventHandlers(event Event) []EventHandler {
s.mutex.RLock()
defer s.mutex.RUnlock()
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 {
t := reflect.TypeOf(v)
if t.Kind() == reflect.Ptr {
@ -165,6 +194,7 @@ func typeName(v interface{}) string {
return t.Name()
}
// applyCommandMiddleware applies a chain of middlewares to a CommandHandler.
func applyCommandMiddleware(
handler CommandHandler, middlewares []CommandMiddleware,
) CommandHandler {
@ -174,6 +204,7 @@ func applyCommandMiddleware(
return handler
}
// applyQueryMiddleware applies a chain of middlewares to a QueryHandler.
func applyQueryMiddleware(
handler QueryHandler, middlewares []QueryMiddleware,
) QueryHandler {
@ -183,6 +214,7 @@ func applyQueryMiddleware(
return handler
}
// applyEventMiddleware applies a chain of middleware to an EventHandler.
func applyEventMiddleware(
handler EventHandler, middlewares []EventMiddleware,
) EventHandler {