blasphem/pkg/bus/bus.go
2022-12-19 19:24:01 -05:00

80 lines
1.2 KiB
Go

package bus
import (
"sync"
)
type (
Event struct {
EvType string
Data interface{}
}
listeners []chan<- Event
bus struct {
sync.RWMutex
subs map[string]listeners
}
Bus interface {
Sub(topic string, ch chan<- Event)
Unsub(topic string, ch chan<- Event)
Pub(topic string, data interface{})
ShutdownBus()
}
)
func New() Bus {
bus := &bus{
subs: make(map[string]listeners),
}
return bus
}
func (b *bus) Sub(topic string, ch chan<- Event) {
b.Lock()
defer b.Unlock()
if prev, ok := b.subs[topic]; ok {
b.subs[topic] = append(prev, ch)
} else {
b.subs[topic] = append(listeners{}, ch)
}
}
func (b *bus) Unsub(topic string, ch chan<- Event) {
b.Lock()
defer b.Unlock()
for i, v := range b.subs[topic] {
if v == ch {
// we don't care about order, replace and reslice
b.subs[topic][i] = b.subs[topic][len(b.subs[topic])-1]
b.subs[topic] = b.subs[topic][:len(b.subs[topic])-1]
}
}
}
func (b *bus) Pub(topic string, data interface{}) {
b.RLock()
defer b.RUnlock()
tc, ok := b.subs[topic]
if !ok {
return
}
for _, ch := range tc {
ch <- Event{EvType: topic, Data: data}
}
}
func (b *bus) ShutdownBus() {
for _, v := range b.subs {
for _, c := range v {
close(c)
}
}
}