init push
This commit is contained in:
145
internal/queue/enqueuer.go
Normal file
145
internal/queue/enqueuer.go
Normal file
@@ -0,0 +1,145 @@
|
||||
package queue
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
type ProducerMetrics struct {
|
||||
published int64
|
||||
publishFailures int64
|
||||
secondaryFailures int64
|
||||
}
|
||||
|
||||
type EmailEnqueuer struct {
|
||||
serializer MessageSerializer
|
||||
producer QueueProducer
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func NewEmailEnqueuer(serializer MessageSerializer, producer QueueProducer, logger *slog.Logger) *EmailEnqueuer {
|
||||
if logger == nil {
|
||||
logger = slog.Default()
|
||||
}
|
||||
return &EmailEnqueuer{
|
||||
serializer: serializer,
|
||||
producer: producer,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *EmailEnqueuer) Enqueue(ctx context.Context, job EmailJob) error {
|
||||
message, err := e.serializer.Serialize(ctx, job)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := e.producer.Publish(ctx, *message); err != nil {
|
||||
e.logger.Error("queue publish failed",
|
||||
slog.String("backend", e.producer.Backend()),
|
||||
slog.String("message_id", message.ID),
|
||||
slog.String("job_type", job.NormalizedType()),
|
||||
slog.String("recipient_hash", job.RecipientHash()),
|
||||
slog.String("correlation_id", message.Attributes["correlation_id"]),
|
||||
slog.Any("error", err),
|
||||
)
|
||||
return err
|
||||
}
|
||||
e.logger.Info("queue published",
|
||||
slog.String("backend", e.producer.Backend()),
|
||||
slog.String("message_id", message.ID),
|
||||
slog.String("job_type", job.NormalizedType()),
|
||||
slog.String("recipient_hash", job.RecipientHash()),
|
||||
slog.String("correlation_id", message.Attributes["correlation_id"]),
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
type DualProducer struct {
|
||||
primary QueueProducer
|
||||
secondary QueueProducer
|
||||
secondaryRequired bool
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func NewDualProducer(primary, secondary QueueProducer, secondaryRequired bool, logger *slog.Logger) *DualProducer {
|
||||
if logger == nil {
|
||||
logger = slog.Default()
|
||||
}
|
||||
return &DualProducer{
|
||||
primary: primary,
|
||||
secondary: secondary,
|
||||
secondaryRequired: secondaryRequired,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *DualProducer) Backend() string {
|
||||
return "dual"
|
||||
}
|
||||
|
||||
func (p *DualProducer) Publish(ctx context.Context, message OutboundMessage) error {
|
||||
if p.primary == nil {
|
||||
return errors.New("primary producer is required")
|
||||
}
|
||||
if err := p.primary.Publish(ctx, message); err != nil {
|
||||
return err
|
||||
}
|
||||
if p.secondary == nil {
|
||||
return nil
|
||||
}
|
||||
if err := p.secondary.Publish(ctx, message); err != nil {
|
||||
p.logger.Error("queue secondary publish failed",
|
||||
slog.String("primary_backend", p.primary.Backend()),
|
||||
slog.String("secondary_backend", p.secondary.Backend()),
|
||||
slog.String("message_id", message.ID),
|
||||
slog.Any("error", err),
|
||||
)
|
||||
if p.secondaryRequired {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DualEmailJobProducer struct {
|
||||
primary EmailJobProducer
|
||||
secondary EmailJobProducer
|
||||
secondaryRequired bool
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func NewDualEmailJobProducer(primary, secondary EmailJobProducer, secondaryRequired bool, logger *slog.Logger) *DualEmailJobProducer {
|
||||
if logger == nil {
|
||||
logger = slog.Default()
|
||||
}
|
||||
return &DualEmailJobProducer{
|
||||
primary: primary,
|
||||
secondary: secondary,
|
||||
secondaryRequired: secondaryRequired,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *DualEmailJobProducer) Enqueue(ctx context.Context, job EmailJob) error {
|
||||
if p.primary == nil {
|
||||
return errors.New("primary email producer is required")
|
||||
}
|
||||
if err := p.primary.Enqueue(ctx, job); err != nil {
|
||||
return err
|
||||
}
|
||||
if p.secondary == nil {
|
||||
return nil
|
||||
}
|
||||
if err := p.secondary.Enqueue(ctx, job); err != nil {
|
||||
p.logger.Error("queue secondary enqueue failed",
|
||||
slog.String("job_type", job.NormalizedType()),
|
||||
slog.String("recipient_hash", job.RecipientHash()),
|
||||
slog.Any("error", err),
|
||||
)
|
||||
if p.secondaryRequired {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user