Files
sendico/api/pkg/messaging/consumer/consumer.go
2026-01-04 12:57:40 +01:00

67 lines
1.7 KiB
Go

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
}