service backend
All checks were successful
ci/woodpecker/push/db Pipeline was successful
ci/woodpecker/push/nats Pipeline was successful

This commit is contained in:
Stephan D
2025-11-07 18:35:26 +01:00
parent 20e8f9acc4
commit 62a6631b9a
537 changed files with 48453 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
package inprocess
import (
"fmt"
"sync"
"github.com/tech/sendico/pkg/merrors"
me "github.com/tech/sendico/pkg/messaging/envelope"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/model"
"github.com/tech/sendico/pkg/mutil/mzap"
"go.uber.org/zap"
)
type MessageBroker struct {
logger mlogger.Logger
subscribers map[string][]chan me.Envelope
lock sync.RWMutex
bufferSize int
}
func (b *MessageBroker) Publish(envelope me.Envelope) error {
topic := envelope.GetSignature().ToString()
b.logger.Debug("Publishing message", mzap.Envelope(envelope))
b.lock.RLock()
defer b.lock.RUnlock()
if subs, ok := b.subscribers[topic]; ok {
for _, sub := range subs {
select {
case sub <- envelope:
default:
}
}
return nil
}
b.logger.Warn("Topic not found", mzap.Envelope(envelope))
return merrors.NoMessagingTopic(topic)
}
func (b *MessageBroker) Subscribe(event model.NotificationEvent) (<-chan me.Envelope, error) {
topic := event.ToString()
b.logger.Info("New topic subscriber", zap.String("topic", topic))
ch := make(chan me.Envelope, b.bufferSize) // Buffered channel to avoid blocking publishers
{
b.lock.Lock()
defer b.lock.Unlock()
b.subscribers[topic] = append(b.subscribers[topic], ch)
}
return ch, nil
}
func (b *MessageBroker) Unsubscribe(event model.NotificationEvent, subChan <-chan me.Envelope) error {
topic := event.ToString()
b.logger.Info("Unsubscribing topic", zap.String("topic", topic))
b.lock.Lock()
defer b.lock.Unlock()
subs, ok := b.subscribers[topic]
if !ok {
b.logger.Debug("No subscribers for topic", zap.String("topic", topic))
return nil
}
for i, ch := range subs {
if ch == subChan {
b.subscribers[topic] = append(subs[:i], subs[i+1:]...)
close(ch)
return nil
}
}
b.logger.Warn("No topic found", zap.String("topic", topic))
return merrors.NoMessagingTopic(topic)
}
func NewInProcessBroker(logger mlogger.Logger, bufferSize int) (*MessageBroker, error) {
if bufferSize < 1 {
return nil, merrors.InvalidArgument(fmt.Sprintf("Invelid buffer size %d. It must be greater than 1", bufferSize))
}
logger.Info("Created in-process logger", zap.Int("buffer_size", bufferSize))
return &MessageBroker{
logger: logger.Named("in_process"),
subscribers: make(map[string][]chan me.Envelope),
bufferSize: bufferSize,
}, nil
}

View File

@@ -0,0 +1,5 @@
package inprocess
type MessagingConfig struct {
BufferSize int `mapstructure:"buffer_size" yaml:"buffer_size"`
}