rwadurian/backend/mpc-system/services/message-router/domain/session_event_broadcaster.go

84 lines
2.0 KiB
Go

package domain
import (
"sync"
pb "github.com/rwadurian/mpc-system/api/grpc/router/v1"
)
// SessionEventBroadcaster manages session event subscriptions and broadcasting
type SessionEventBroadcaster struct {
subscribers map[string]chan *pb.SessionEvent // partyID -> event channel
mu sync.RWMutex
}
// NewSessionEventBroadcaster creates a new session event broadcaster
func NewSessionEventBroadcaster() *SessionEventBroadcaster {
return &SessionEventBroadcaster{
subscribers: make(map[string]chan *pb.SessionEvent),
}
}
// Subscribe subscribes a party to session events
func (b *SessionEventBroadcaster) Subscribe(partyID string) <-chan *pb.SessionEvent {
b.mu.Lock()
defer b.mu.Unlock()
// Create buffered channel for this subscriber
ch := make(chan *pb.SessionEvent, 100)
b.subscribers[partyID] = ch
return ch
}
// Unsubscribe removes a party's subscription
func (b *SessionEventBroadcaster) Unsubscribe(partyID string) {
b.mu.Lock()
defer b.mu.Unlock()
if ch, exists := b.subscribers[partyID]; exists {
close(ch)
delete(b.subscribers, partyID)
}
}
// Broadcast sends an event to all subscribers
func (b *SessionEventBroadcaster) Broadcast(event *pb.SessionEvent) {
b.mu.RLock()
defer b.mu.RUnlock()
for _, ch := range b.subscribers {
// Non-blocking send to prevent slow subscribers from blocking
select {
case ch <- event:
default:
// Channel full, skip this subscriber
}
}
}
// BroadcastToParties sends an event to specific parties only
func (b *SessionEventBroadcaster) BroadcastToParties(event *pb.SessionEvent, partyIDs []string) {
b.mu.RLock()
defer b.mu.RUnlock()
for _, partyID := range partyIDs {
if ch, exists := b.subscribers[partyID]; exists {
// Non-blocking send
select {
case ch <- event:
default:
// Channel full, skip this subscriber
}
}
}
}
// SubscriberCount returns the number of active subscribers
func (b *SessionEventBroadcaster) SubscriberCount() int {
b.mu.RLock()
defer b.mu.RUnlock()
return len(b.subscribers)
}