1
0

GODT-2002: Wait for API events to be applied after send

When we send a message, the send recorder records the sent message.
When the client then appends an identical message to the sent folder,
the deduplication works and instead returns the message ID of the
existing proton message, rather than creating a new message. Gluon is
expected to notice that it already has this message ID and perform
some deduplication stuff internally.

However, it can happen that gluon doesn't yet have this message ID,
because we haven't yet received the "Message Created" event from the
API. To prevent this, we poll the events after send and wait for all
new events to be applied.

There's still a chance that the event wasn't generated yet on the API
side. Not sure what we can do about this.
This commit is contained in:
James Houlahan
2022-11-19 16:38:54 +01:00
parent e6a780ebd4
commit 721cd9f319
2 changed files with 53 additions and 18 deletions

View File

@ -86,7 +86,7 @@ func (conn *imapConnector) Authorize(username string, password []byte) bool {
// CreateMailbox creates a label with the given name.
func (conn *imapConnector) CreateMailbox(ctx context.Context, name []string) (imap.Mailbox, error) {
defer conn.goPoll()
defer conn.goPoll(false)
if len(name) < 2 {
return imap.Mailbox{}, fmt.Errorf("invalid mailbox name %q", name)
@ -157,7 +157,7 @@ func (conn *imapConnector) createFolder(ctx context.Context, name []string) (ima
// UpdateMailboxName sets the name of the label with the given ID.
func (conn *imapConnector) UpdateMailboxName(ctx context.Context, labelID imap.MailboxID, name []string) error {
defer conn.goPoll()
defer conn.goPoll(false)
if len(name) < 2 {
return fmt.Errorf("invalid mailbox name %q", name)
@ -234,7 +234,7 @@ func (conn *imapConnector) updateFolder(ctx context.Context, labelID imap.Mailbo
// DeleteMailbox deletes the label with the given ID.
func (conn *imapConnector) DeleteMailbox(ctx context.Context, labelID imap.MailboxID) error {
defer conn.goPoll()
defer conn.goPoll(false)
return conn.client.DeleteLabel(ctx, string(labelID))
}
@ -249,7 +249,7 @@ func (conn *imapConnector) CreateMessage(
flags imap.FlagSet,
date time.Time,
) (imap.Message, []byte, error) {
defer conn.goPoll()
defer conn.goPoll(false)
// Compute the hash of the message (to match it against SMTP messages).
hash, err := getMessageHash(literal)
@ -313,14 +313,14 @@ func (conn *imapConnector) CreateMessage(
// AddMessagesToMailbox labels the given messages with the given label ID.
func (conn *imapConnector) AddMessagesToMailbox(ctx context.Context, messageIDs []imap.MessageID, mailboxID imap.MailboxID) error {
defer conn.goPoll()
defer conn.goPoll(false)
return conn.client.LabelMessages(ctx, mapTo[imap.MessageID, string](messageIDs), string(mailboxID))
}
// RemoveMessagesFromMailbox unlabels the given messages with the given label ID.
func (conn *imapConnector) RemoveMessagesFromMailbox(ctx context.Context, messageIDs []imap.MessageID, mailboxID imap.MailboxID) error {
defer conn.goPoll()
defer conn.goPoll(false)
if err := conn.client.UnlabelMessages(ctx, mapTo[imap.MessageID, string](messageIDs), string(mailboxID)); err != nil {
return err
@ -363,7 +363,7 @@ func (conn *imapConnector) RemoveMessagesFromMailbox(ctx context.Context, messag
// MoveMessages removes the given messages from one label and adds them to the other label.
func (conn *imapConnector) MoveMessages(ctx context.Context, messageIDs []imap.MessageID, labelFromID imap.MailboxID, labelToID imap.MailboxID) error {
defer conn.goPoll()
defer conn.goPoll(false)
if err := conn.client.LabelMessages(ctx, mapTo[imap.MessageID, string](messageIDs), string(labelToID)); err != nil {
return fmt.Errorf("labeling messages: %w", err)
@ -378,7 +378,7 @@ func (conn *imapConnector) MoveMessages(ctx context.Context, messageIDs []imap.M
// MarkMessagesSeen sets the seen value of the given messages.
func (conn *imapConnector) MarkMessagesSeen(ctx context.Context, messageIDs []imap.MessageID, seen bool) error {
defer conn.goPoll()
defer conn.goPoll(false)
if seen {
return conn.client.MarkMessagesRead(ctx, mapTo[imap.MessageID, string](messageIDs)...)
@ -389,7 +389,7 @@ func (conn *imapConnector) MarkMessagesSeen(ctx context.Context, messageIDs []im
// MarkMessagesFlagged sets the flagged value of the given messages.
func (conn *imapConnector) MarkMessagesFlagged(ctx context.Context, messageIDs []imap.MessageID, flagged bool) error {
defer conn.goPoll()
defer conn.goPoll(false)
if flagged {
return conn.client.LabelMessages(ctx, mapTo[imap.MessageID, string](messageIDs), liteapi.StarredLabel)