Merge branch 'events' into imap

This commit is contained in:
emersion 2018-01-12 12:05:23 +01:00
commit 12cccff787
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
2 changed files with 74 additions and 3 deletions

View File

@ -17,6 +17,7 @@ import (
"github.com/emersion/hydroxide/auth"
"github.com/emersion/hydroxide/carddav"
"github.com/emersion/hydroxide/events"
"github.com/emersion/hydroxide/protonmail"
imapbackend "github.com/emersion/hydroxide/imap"
smtpbackend "github.com/emersion/hydroxide/smtp"
@ -175,6 +176,8 @@ func main() {
port = "8080"
}
eventsManager := events.NewManager()
sessions := auth.NewManager(newClient)
handlers := make(map[string]http.Handler)
@ -203,9 +206,9 @@ func main() {
h, ok := handlers[username]
if !ok {
events := make(chan *protonmail.Event)
go receiveEvents(c, "", events)
h = carddav.NewHandler(c, privateKeys, events)
ch := make(chan *protonmail.Event)
eventsManager.Register(c, username, ch)
h = carddav.NewHandler(c, privateKeys, ch)
handlers[username] = h
}

68
events/events.go Normal file
View File

@ -0,0 +1,68 @@
package events
import (
"log"
"sync"
"time"
"github.com/emersion/hydroxide/protonmail"
)
const pollInterval = time.Minute
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()
for _, ch := range r.channels {
ch <- event
}
r.locker.Unlock()
}
}
type Manager struct {
receivers map[string]*receiver
locker sync.Mutex
}
func NewManager() *Manager {
return &Manager{
receivers: make(map[string]*receiver),
}
}
func (m *Manager) Register(c *protonmail.Client, username string, ch chan<- *protonmail.Event) {
m.locker.Lock()
defer m.locker.Unlock()
if r, ok := m.receivers[username]; ok {
r.locker.Lock()
r.channels = append(r.channels, ch)
r.locker.Unlock()
} else {
r = &receiver{
channels: []chan<- *protonmail.Event{ch},
}
go r.receiveEvents(c, "")
m.receivers[username] = r
}
}