From 457ff24dccfb0a94730763f60a68c804c53283c7 Mon Sep 17 00:00:00 2001 From: Rene Nochebuena Date: Sat, 26 Apr 2025 22:33:20 -0600 Subject: [PATCH] Add comprehensive documentation for Singularity struct methods 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. --- cqrs/singularity.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/cqrs/singularity.go b/cqrs/singularity.go index cf24258..e6f94ac 100644 --- a/cqrs/singularity.go +++ b/cqrs/singularity.go @@ -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 {