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 }