woodpecker/server/pubsub/pub.go
2023-03-18 20:35:27 +01:00

75 lines
1.1 KiB
Go

package pubsub
import (
"context"
"sync"
)
type subscriber struct {
receiver Receiver
}
type publisher struct {
sync.Mutex
topics map[string]*topic
}
// New creates an in-memory publisher.
func New() Publisher {
return &publisher{
topics: make(map[string]*topic),
}
}
func (p *publisher) Create(_ context.Context, dest string) error {
p.Lock()
_, ok := p.topics[dest]
if !ok {
t := newTopic(dest)
p.topics[dest] = t
}
p.Unlock()
return nil
}
func (p *publisher) Publish(_ context.Context, dest string, message Message) error {
p.Lock()
t, ok := p.topics[dest]
p.Unlock()
if !ok {
return ErrNotFound
}
t.publish(message)
return nil
}
func (p *publisher) Subscribe(c context.Context, dest string, receiver Receiver) error {
p.Lock()
t, ok := p.topics[dest]
p.Unlock()
if !ok {
return ErrNotFound
}
s := &subscriber{
receiver: receiver,
}
t.subscribe(s)
select {
case <-c.Done():
case <-t.done:
}
t.unsubscribe(s)
return nil
}
func (p *publisher) Remove(_ context.Context, dest string) error {
p.Lock()
t, ok := p.topics[dest]
if ok {
delete(p.topics, dest)
t.close()
}
p.Unlock()
return nil
}