github.com/wfusion/gofusion@v1.1.14/common/infra/watermill/components/cqrs/command_handler.go (about)

     1  package cqrs
     2  
     3  import (
     4  	"context"
     5  )
     6  
     7  // CommandHandler receives a command defined by NewCommand and handles it with the Handle method.
     8  // If using DDD, CommandHandler may modify and persist the aggregate.
     9  //
    10  // In contrast to EventHandler, every Command must have only one CommandHandler.
    11  //
    12  // One instance of CommandHandler is used during handling messages.
    13  // When multiple commands are delivered at the same time, Handle method can be executed multiple times at the same time.
    14  // Because of that, Handle method needs to be thread safe!
    15  type CommandHandler interface {
    16  	// HandlerName is the name used in message.Router while creating handler.
    17  	//
    18  	// It will be also passed to CommandsSubscriberConstructor.
    19  	// May be useful, for example, to create a consumer group per each handler.
    20  	//
    21  	// WARNING: If HandlerName was changed and is used for generating consumer groups,
    22  	// it may result with **reconsuming all messages**!
    23  	HandlerName() string
    24  
    25  	NewCommand() any
    26  
    27  	Handle(ctx context.Context, cmd any) error
    28  }
    29  
    30  type genericCommandHandler[Command any] struct {
    31  	handleFunc  func(ctx context.Context, cmd *Command) error
    32  	handlerName string
    33  }
    34  
    35  // NewCommandHandler creates a new CommandHandler implementation based on provided function
    36  // and command type inferred from function argument.
    37  func NewCommandHandler[Command any](
    38  	handlerName string,
    39  	handleFunc func(ctx context.Context, cmd *Command) error,
    40  ) CommandHandler {
    41  	return &genericCommandHandler[Command]{
    42  		handleFunc:  handleFunc,
    43  		handlerName: handlerName,
    44  	}
    45  }
    46  
    47  func (c genericCommandHandler[Command]) HandlerName() string {
    48  	return c.handlerName
    49  }
    50  
    51  func (c genericCommandHandler[Command]) NewCommand() any {
    52  	tVar := new(Command)
    53  	return tVar
    54  }
    55  
    56  func (c genericCommandHandler[Command]) Handle(ctx context.Context, cmd any) error {
    57  	command := cmd.(*Command)
    58  	return c.handleFunc(ctx, command)
    59  }