@@ -18,14 +18,14 @@ import (
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
cfg *config.Config
|
||||
store *db.Store
|
||||
client *http.Client
|
||||
stop chan struct{}
|
||||
once sync.Once
|
||||
mu sync.RWMutex
|
||||
jobs map[string]CheckJob
|
||||
events chan Event
|
||||
cfg *config.Config
|
||||
store *db.Store
|
||||
client *http.Client
|
||||
stop chan struct{}
|
||||
once sync.Once
|
||||
mu sync.RWMutex
|
||||
jobs map[string]CheckJob
|
||||
subscribers map[chan Event]struct{}
|
||||
}
|
||||
|
||||
type Event struct {
|
||||
@@ -68,12 +68,12 @@ type legacySubcategory struct {
|
||||
|
||||
func NewService(cfg *config.Config, store *db.Store) *Service {
|
||||
return &Service{
|
||||
cfg: cfg,
|
||||
store: store,
|
||||
client: &http.Client{Timeout: 10 * time.Second},
|
||||
stop: make(chan struct{}),
|
||||
jobs: map[string]CheckJob{},
|
||||
events: make(chan Event, 32),
|
||||
cfg: cfg,
|
||||
store: store,
|
||||
client: &http.Client{Timeout: 10 * time.Second},
|
||||
stop: make(chan struct{}),
|
||||
jobs: map[string]CheckJob{},
|
||||
subscribers: map[chan Event]struct{}{},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,8 +296,20 @@ func (s *Service) CheckJob(id string) (CheckJob, bool) {
|
||||
return item, ok
|
||||
}
|
||||
|
||||
func (s *Service) Events() <-chan Event {
|
||||
return s.events
|
||||
func (s *Service) SubscribeEvents() (<-chan Event, func()) {
|
||||
ch := make(chan Event, 16)
|
||||
s.mu.Lock()
|
||||
s.subscribers[ch] = struct{}{}
|
||||
s.mu.Unlock()
|
||||
unsubscribe := func() {
|
||||
s.mu.Lock()
|
||||
if _, ok := s.subscribers[ch]; ok {
|
||||
delete(s.subscribers, ch)
|
||||
close(ch)
|
||||
}
|
||||
s.mu.Unlock()
|
||||
}
|
||||
return ch, unsubscribe
|
||||
}
|
||||
|
||||
func (s *Service) runCheckJob(ctx context.Context, id string, items []db.Source) {
|
||||
@@ -445,9 +457,13 @@ func (s *Service) updateJob(id string, mutate func(*CheckJob)) {
|
||||
|
||||
func (s *Service) emit(kind string, data map[string]any) {
|
||||
event := Event{Type: kind, Data: data}
|
||||
select {
|
||||
case s.events <- event:
|
||||
default:
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
for ch := range s.subscribers {
|
||||
select {
|
||||
case ch <- event:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user