package main import ( "errors" ) type Notifier[TNotification any] struct { bufferSize int Listeners map[string]chan TNotification } func (n *Notifier[TNotification]) Create(id string) error { if _, exists := n.Listeners[id]; exists { return errors.New("This listener already exists") } n.Listeners[id] = make(chan TNotification, n.bufferSize) return nil } var ChannelFullErr = errors.New("Channel is full") // Ensures the listener exists before sending func (n *Notifier[TNotification]) SendAndCreate(id string, notification TNotification) error { if _, exists := n.Listeners[id]; !exists { if err := n.Create(id); err != nil { return err } } ch := n.Listeners[id] select { case ch <- notification: return nil default: return ChannelFullErr } } func (n *Notifier[TNotification]) Delete(id string) error { if _, exists := n.Listeners[id]; !exists { return errors.New("This listener does not exists") } delete(n.Listeners, id) return nil } func NewNotifier[TNotification any](bufferSize int) Notifier[TNotification] { return Notifier[TNotification]{ bufferSize: bufferSize, Listeners: make(map[string]chan TNotification), } } // ---------------------------------- type ChannelSplitter[TNotification any] struct { ch chan TNotification Listeners map[string]chan TNotification } func (s *ChannelSplitter[TNotification]) Listen() { go func() { for { select { case msg := <-s.ch: for _, v := range s.Listeners { v <- msg } } } }() } func (s *ChannelSplitter[TNotification]) Add(id string) chan TNotification { ch := make(chan TNotification) s.Listeners[id] = ch return ch } func (s *ChannelSplitter[TNotification]) Remove(id string) { delete(s.Listeners, id) } func NewChannelSplitter[TNotification any](ch chan TNotification) ChannelSplitter[TNotification] { return ChannelSplitter[TNotification]{ ch: ch, Listeners: make(map[string]chan TNotification), } }