110 lines
2.7 KiB
Go
110 lines
2.7 KiB
Go
package backend
|
|
|
|
import (
|
|
"github.com/emersion/go-imap"
|
|
)
|
|
|
|
// Update contains user and mailbox information about an unilateral backend
|
|
// update.
|
|
type Update struct {
|
|
// The user targeted by this update. If empty, all connected users will
|
|
// be notified.
|
|
Username string
|
|
// The mailbox targeted by this update. If empty, the update targets all
|
|
// mailboxes.
|
|
Mailbox string
|
|
|
|
// A channel that will be closed once the update has been processed.
|
|
done chan struct{}
|
|
}
|
|
|
|
// Done returns a channel that is closed when the update has been broadcast to
|
|
// all clients.
|
|
func (u *Update) Done() <-chan struct{} {
|
|
if u.done == nil {
|
|
u.done = make(chan struct{})
|
|
}
|
|
return u.done
|
|
}
|
|
|
|
// DoneUpdate marks an update as done.
|
|
// TODO: remove this function
|
|
func DoneUpdate(u *Update) {
|
|
if u.done != nil {
|
|
close(u.done)
|
|
}
|
|
}
|
|
|
|
// StatusUpdate is a status update. See RFC 3501 section 7.1 for a list of
|
|
// status responses.
|
|
type StatusUpdate struct {
|
|
Update
|
|
*imap.StatusResp
|
|
}
|
|
|
|
// MailboxUpdate is a mailbox update.
|
|
type MailboxUpdate struct {
|
|
Update
|
|
*imap.MailboxStatus
|
|
}
|
|
|
|
// MessageUpdate is a message update.
|
|
type MessageUpdate struct {
|
|
Update
|
|
*imap.Message
|
|
}
|
|
|
|
// ExpungeUpdate is an expunge update.
|
|
type ExpungeUpdate struct {
|
|
Update
|
|
SeqNum uint32
|
|
}
|
|
|
|
// Updater is a Backend that implements Updater is able to send unilateral
|
|
// backend updates. Backends not implementing this interface don't correctly
|
|
// send unilateral updates, for instance if a user logs in from two connections
|
|
// and deletes a message from one of them, the over is not aware that such a
|
|
// mesage has been deleted. More importantly, backends implementing Updater can
|
|
// notify the user for external updates such as new message notifications.
|
|
type Updater interface {
|
|
// Updates returns a set of channels where updates are sent to.
|
|
Updates() <-chan interface{}
|
|
}
|
|
|
|
// UpdaterMailbox is a Mailbox that implements UpdaterMailbox is able to poll
|
|
// updates for new messages or message status updates during a period of
|
|
// inactivity.
|
|
type UpdaterMailbox interface {
|
|
// Poll requests mailbox updates.
|
|
Poll() error
|
|
}
|
|
|
|
// WaitUpdates returns a channel that's closed when all provided updates have
|
|
// been dispatched to all clients. It panics if one of the provided value is
|
|
// not an update.
|
|
func WaitUpdates(updates ...interface{}) <-chan struct{} {
|
|
done := make(chan struct{})
|
|
|
|
var chs []<-chan struct{}
|
|
for _, u := range updates {
|
|
uu, ok := u.(interface {
|
|
Done() <-chan struct{}
|
|
})
|
|
if !ok {
|
|
panic("imap: cannot wait for update: provided value is not a valid update")
|
|
}
|
|
|
|
chs = append(chs, uu.Done())
|
|
}
|
|
|
|
go func() {
|
|
// Wait for all updates to be sent
|
|
for _, ch := range chs {
|
|
<-ch
|
|
}
|
|
close(done)
|
|
}()
|
|
|
|
return done
|
|
}
|