1
0
Fork 0
forked from mirrors/ntfy
ntfy/server/topic.go

76 lines
1.4 KiB
Go
Raw Normal View History

2021-10-23 01:26:01 +00:00
package server
import (
"context"
"errors"
"log"
"math/rand"
"sync"
"time"
)
type topic struct {
id string
subscribers map[int]subscriber
2021-10-23 19:22:17 +00:00
messages int
2021-10-23 01:26:01 +00:00
last time.Time
2021-10-23 19:22:17 +00:00
ctx context.Context
cancel context.CancelFunc
mu sync.Mutex
2021-10-23 01:26:01 +00:00
}
type subscriber func(msg *message) error
func newTopic(id string) *topic {
ctx, cancel := context.WithCancel(context.Background())
return &topic{
id: id,
subscribers: make(map[int]subscriber),
last: time.Now(),
ctx: ctx,
cancel: cancel,
}
}
func (t *topic) Subscribe(s subscriber) int {
t.mu.Lock()
defer t.mu.Unlock()
subscriberID := rand.Int()
t.subscribers[subscriberID] = s
t.last = time.Now()
return subscriberID
}
func (t *topic) Unsubscribe(id int) int {
2021-10-23 01:26:01 +00:00
t.mu.Lock()
defer t.mu.Unlock()
delete(t.subscribers, id)
return len(t.subscribers)
2021-10-23 01:26:01 +00:00
}
func (t *topic) Publish(m *message) error {
t.mu.Lock()
defer t.mu.Unlock()
if len(t.subscribers) == 0 {
return errors.New("no subscribers")
}
t.last = time.Now()
t.messages++
for _, s := range t.subscribers {
if err := s(m); err != nil {
log.Printf("error publishing message to subscriber")
2021-10-23 01:26:01 +00:00
}
}
return nil
}
func (t *topic) Stats() (subscribers int, messages int) {
t.mu.Lock()
defer t.mu.Unlock()
return len(t.subscribers), t.messages
}
2021-10-23 01:26:01 +00:00
func (t *topic) Close() {
t.cancel()
}