84 lines
2.0 KiB
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)
|
|
}
|