hodu/bulletin.go

85 lines
1.6 KiB
Go

package hodu
import "container/list"
import "sync"
type BulletinChan = chan interface{}
type BulletinSubscription struct {
c chan interface{}
b *Bulletin
topic string
node *list.Element
}
type BulletinSubscriptionList = *list.List
type BulletinSubscriptionMap map[string]BulletinSubscriptionList
type Bulletin struct {
sbsc_map BulletinSubscriptionMap
sbsc_mtx sync.RWMutex
}
func NewBulletin() *Bulletin {
return &Bulletin{
sbsc_map: make(BulletinSubscriptionMap, 0),
}
}
func (b *Bulletin) Subscribe(topic string) *BulletinSubscription {
var sbsc BulletinSubscription
var sbsc_list BulletinSubscriptionList
var ok bool
sbsc.b = b
sbsc.c = make(chan interface{})
sbsc.topic = topic
b.sbsc_mtx.Lock()
sbsc_list, ok = b.sbsc_map[topic]
if !ok {
sbsc_list = list.New()
b.sbsc_map[topic] = sbsc_list
}
sbsc.node = sbsc_list.PushBack(&sbsc)
b.sbsc_mtx.Unlock()
return &sbsc
}
func (b *Bulletin) Unsbsccribe(sbsc *BulletinSubscription) {
if sbsc.b == b {
var sl BulletinSubscriptionList
var ok bool
b.sbsc_mtx.Lock()
sl, ok = b.sbsc_map[sbsc.topic]
if ok { sl.Remove(sbsc.node) }
b.sbsc_mtx.Unlock()
}
}
func (b *Bulletin) Publish(topic string, data interface{}) {
var sl BulletinSubscriptionList
var ok bool
b.sbsc_mtx.Lock()
sl, ok = b.sbsc_map[topic]
if ok {
var sbsc *BulletinSubscription
var e *list.Element
for e = sl.Front(); e != nil; e = e.Next() {
sbsc = e.Value.(*BulletinSubscription)
sbsc.c <- data
}
}
b.sbsc_mtx.Unlock()
}
func (s *BulletinSubscription) Receive() interface{} {
var x interface{}
x = <- s.c
return x
}