2018-01-11 19:17:11 +02:00
|
|
|
package events
|
|
|
|
|
|
|
|
import (
|
|
|
|
"log"
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/emersion/hydroxide/protonmail"
|
|
|
|
)
|
|
|
|
|
2018-01-12 14:20:17 +02:00
|
|
|
const pollInterval = 30 * time.Second
|
2018-01-11 19:17:11 +02:00
|
|
|
|
|
|
|
type receiver struct {
|
|
|
|
channels []chan<- *protonmail.Event
|
|
|
|
locker sync.Mutex
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *receiver) receiveEvents(c *protonmail.Client, last string) {
|
|
|
|
t := time.NewTicker(pollInterval)
|
|
|
|
defer t.Stop()
|
|
|
|
|
|
|
|
for range t.C {
|
|
|
|
event, err := c.GetEvent(last)
|
|
|
|
if err != nil {
|
|
|
|
log.Println("cannot receive event:", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if event.ID == last {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
last = event.ID
|
|
|
|
|
|
|
|
r.locker.Lock()
|
2018-01-12 14:20:17 +02:00
|
|
|
n := len(r.channels)
|
2018-01-11 19:17:11 +02:00
|
|
|
for _, ch := range r.channels {
|
|
|
|
ch <- event
|
|
|
|
}
|
|
|
|
r.locker.Unlock()
|
2018-01-12 14:20:17 +02:00
|
|
|
|
|
|
|
if n == 0 {
|
|
|
|
break
|
|
|
|
}
|
2018-01-11 19:17:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type Manager struct {
|
|
|
|
receivers map[string]*receiver
|
|
|
|
locker sync.Mutex
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewManager() *Manager {
|
|
|
|
return &Manager{
|
|
|
|
receivers: make(map[string]*receiver),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-12 14:20:17 +02:00
|
|
|
func (m *Manager) Register(c *protonmail.Client, username string, ch chan<- *protonmail.Event, done <-chan struct{}) {
|
2018-01-11 19:17:11 +02:00
|
|
|
m.locker.Lock()
|
|
|
|
defer m.locker.Unlock()
|
|
|
|
|
2018-01-12 14:20:17 +02:00
|
|
|
r, ok := m.receivers[username]
|
|
|
|
if ok {
|
2018-01-11 19:17:11 +02:00
|
|
|
r.locker.Lock()
|
|
|
|
r.channels = append(r.channels, ch)
|
|
|
|
r.locker.Unlock()
|
|
|
|
} else {
|
|
|
|
r = &receiver{
|
|
|
|
channels: []chan<- *protonmail.Event{ch},
|
|
|
|
}
|
2018-01-12 14:20:17 +02:00
|
|
|
|
|
|
|
go func() {
|
|
|
|
r.receiveEvents(c, "")
|
|
|
|
|
|
|
|
m.locker.Lock()
|
|
|
|
delete(m.receivers, username)
|
|
|
|
m.locker.Unlock()
|
|
|
|
}()
|
|
|
|
|
2018-01-11 19:17:11 +02:00
|
|
|
m.receivers[username] = r
|
|
|
|
}
|
2018-01-12 14:20:17 +02:00
|
|
|
|
|
|
|
if done != nil {
|
|
|
|
go func() {
|
|
|
|
<-done
|
|
|
|
|
|
|
|
r.locker.Lock()
|
|
|
|
for i, c := range r.channels {
|
|
|
|
if c == ch {
|
|
|
|
r.channels = append(r.channels[:i], r.channels[i+1:]...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
r.locker.Unlock()
|
|
|
|
|
|
|
|
close(ch)
|
|
|
|
}()
|
|
|
|
}
|
2018-01-11 19:17:11 +02:00
|
|
|
}
|