package consumer import ( "context" messaging "github.com/tech/sendico/pkg/messaging" mb "github.com/tech/sendico/pkg/messaging/broker" me "github.com/tech/sendico/pkg/messaging/envelope" "github.com/tech/sendico/pkg/mlogger" "github.com/tech/sendico/pkg/model" "go.uber.org/zap" ) type ChannelConsumer struct { logger mlogger.Logger broker mb.Broker event model.NotificationEvent ch <-chan me.Envelope ctx context.Context cancel context.CancelFunc } func (c *ChannelConsumer) ConsumeMessages(handleFunc messaging.MessageHandlerT) error { c.logger.Info("Message consumer is ready") for { select { case msg := <-c.ch: if msg == nil { // nil message indicates the channel was closed c.logger.Info("Consumer shutting down") return nil } if err := handleFunc(c.ctx, msg); err != nil { c.logger.Warn("Error processing message", zap.Error(err)) } case <-c.ctx.Done(): c.logger.Info("Context done, shutting down") return c.ctx.Err() } } } func (c *ChannelConsumer) Close() { c.logger.Info("Shutting down...") c.cancel() if err := c.broker.Unsubscribe(c.event, c.ch); err != nil { c.logger.Warn("Failed to unsubscribe", zap.Error(err)) } } func NewConsumer(logger mlogger.Logger, broker mb.Broker, event model.NotificationEvent) (*ChannelConsumer, error) { ctx, cancel := context.WithCancel(context.Background()) ch, err := broker.Subscribe(event) if err != nil { logger.Warn("Failed to create channel consumer", zap.Error(err), zap.String("topic", event.ToString())) cancel() return nil, err } return &ChannelConsumer{ logger: logger.Named("consumer").Named(event.ToString()), broker: broker, event: event, ch: ch, ctx: ctx, cancel: cancel, }, nil }