We now close the Channels when its connection is closed so that we never try to send events into a dead channel Add a debug handler showing who is subscribed to what
124 lines
2.6 KiB
Go
124 lines
2.6 KiB
Go
package events
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"time"
|
|
|
|
"git.quimbo.fr/odwrtw/canape/backend/models"
|
|
"github.com/odwrtw/papi"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// TorrentEventer represents the Eventer for torrents
|
|
type TorrentEventer struct {
|
|
*BaseEventer
|
|
done chan struct{}
|
|
pClient *papi.Client
|
|
torrents []papi.Torrent
|
|
}
|
|
|
|
var torrentEventName = "torrents"
|
|
|
|
// NewTorrentEventers returns a new PolochonEventers for torrents
|
|
func NewTorrentEventers() *PolochonEventers {
|
|
eventer := NewEventers()
|
|
eventer.NewEventer = NewTorrentEventer
|
|
eventer.Name = torrentEventName
|
|
return eventer
|
|
}
|
|
|
|
// NewTorrentEventer returns a new Eventer for a specific Polochon
|
|
func NewTorrentEventer(polo *models.Polochon, log *logrus.Entry) (Eventer, error) {
|
|
// Create a new papi client
|
|
client, err := polo.NewPapiClient()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to instanciate polochon client %s", err)
|
|
}
|
|
|
|
// This is the first time this polochon is requested, create the TorrentEventer
|
|
tn := &TorrentEventer{
|
|
BaseEventer: &BaseEventer{
|
|
users: []*Channel{},
|
|
log: log,
|
|
name: torrentEventName,
|
|
},
|
|
pClient: client,
|
|
done: make(chan struct{}),
|
|
torrents: []papi.Torrent{},
|
|
}
|
|
|
|
return tn, nil
|
|
}
|
|
|
|
// Append implements the Eventer interface
|
|
// It just appends a channel to the list of users
|
|
// When the user is appended, send him the torrents infos we have
|
|
func (t *TorrentEventer) Append(chanl *Channel) {
|
|
event := ServerEvent{
|
|
Event: Event{
|
|
Type: torrentEventName,
|
|
Status: OK,
|
|
},
|
|
Data: t.torrents,
|
|
}
|
|
|
|
chanl.sendEvent(event)
|
|
|
|
t.BaseEventer.Append(chanl)
|
|
}
|
|
|
|
// Launch implements the Eventer interface
|
|
// It starts a ticker to fetch torrents and notify the users
|
|
func (t *TorrentEventer) Launch() error {
|
|
// Create the timer that will check for the torrents every X seconds
|
|
timeTicker := time.NewTicker(10 * time.Second)
|
|
defer timeTicker.Stop()
|
|
|
|
err := t.torrentsUpdate()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for {
|
|
select {
|
|
case <-timeTicker.C:
|
|
err := t.torrentsUpdate()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
case <-t.done:
|
|
t.log.Debug("quit torrent notifier")
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
// torrentsUpdate sends to the eventStream if torrents change
|
|
func (t *TorrentEventer) torrentsUpdate() error {
|
|
// Get torrents
|
|
torrents, err := t.pClient.GetTorrents()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if reflect.DeepEqual(t.torrents, torrents) {
|
|
return nil
|
|
}
|
|
|
|
t.log.Debugf("torrents have changed!")
|
|
|
|
t.NotifyAll(torrents)
|
|
|
|
t.torrents = torrents
|
|
|
|
return nil
|
|
}
|
|
|
|
// Finish implements the Eventer interface
|
|
// It is called when there is no more users subscribed
|
|
func (t *TorrentEventer) Finish() {
|
|
t.log.Debugf("sending the done channel")
|
|
t.done <- struct{}{}
|
|
}
|