98 lines
1.9 KiB
Go
98 lines
1.9 KiB
Go
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),
|
|
}
|
|
}
|