2025-03-08 15:17:27 +09:00
|
|
|
package hodu
|
|
|
|
|
2025-03-10 09:33:19 +09:00
|
|
|
import "container/list"
|
|
|
|
import "sync"
|
|
|
|
|
|
|
|
type BulletinChan = chan interface{}
|
2025-03-08 15:17:27 +09:00
|
|
|
|
2025-03-10 09:33:19 +09:00
|
|
|
type BulletinSubscription struct {
|
|
|
|
c chan interface{}
|
|
|
|
b *Bulletin
|
|
|
|
topic string
|
|
|
|
node *list.Element
|
2025-03-08 15:17:27 +09:00
|
|
|
}
|
|
|
|
|
2025-03-10 09:33:19 +09:00
|
|
|
type BulletinSubscriptionList = *list.List
|
|
|
|
type BulletinSubscriptionMap map[string]BulletinSubscriptionList
|
|
|
|
|
2025-03-08 15:17:27 +09:00
|
|
|
type Bulletin struct {
|
2025-03-10 09:33:19 +09:00
|
|
|
sbsc_map BulletinSubscriptionMap
|
|
|
|
sbsc_mtx sync.RWMutex
|
2025-03-08 15:17:27 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewBulletin() *Bulletin {
|
2025-03-10 09:33:19 +09:00
|
|
|
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
|
2025-03-08 15:17:27 +09:00
|
|
|
}
|
|
|
|
|
2025-03-10 09:33:19 +09:00
|
|
|
func (b *Bulletin) Unsbsccribe(sbsc *BulletinSubscription) {
|
|
|
|
if sbsc.b == b {
|
|
|
|
var sl BulletinSubscriptionList
|
|
|
|
var ok bool
|
2025-03-08 15:17:27 +09:00
|
|
|
|
2025-03-10 09:33:19 +09:00
|
|
|
b.sbsc_mtx.Lock()
|
|
|
|
sl, ok = b.sbsc_map[sbsc.topic]
|
|
|
|
if ok { sl.Remove(sbsc.node) }
|
|
|
|
b.sbsc_mtx.Unlock()
|
|
|
|
}
|
2025-03-08 15:17:27 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Bulletin) Publish(topic string, data interface{}) {
|
2025-03-10 09:33:19 +09:00
|
|
|
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
|
2025-03-08 15:17:27 +09:00
|
|
|
}
|