[geary/wip/131-sent-mail: 51/52] Smtp.ClientService: Explcitly poll when waiting for sent mail



commit 0fb0fb42978b6b835e2f1f02a884ddc7b1f4ff8a
Author: Michael Gratton <mike vee net>
Date:   Mon Aug 26 13:10:42 2019 +1000

    Smtp.ClientService: Explcitly poll when waiting for sent mail
    
    At least GMail takes some time to copy new messages to the Sent folder
    on the server side when sending them, which means the mail may not show
    up even after doing a manual remote sync.
    
    This adds an explicit poll, listing new mail in Sent after sending
    a message to check for the sent message showing up.

 src/engine/smtp/smtp-client-service.vala | 57 ++++++++++++++++++++++++--------
 1 file changed, 44 insertions(+), 13 deletions(-)
---
diff --git a/src/engine/smtp/smtp-client-service.vala b/src/engine/smtp/smtp-client-service.vala
index 36c0727b..51dc2f7f 100644
--- a/src/engine/smtp/smtp-client-service.vala
+++ b/src/engine/smtp/smtp-client-service.vala
@@ -234,7 +234,7 @@ internal class Geary.Smtp.ClientService : Geary.ClientService {
         } else {
             debug("Outbox postie: Syncing sent mail to find %s",
                   email.id.to_string());
-            yield sync_sent_mail(cancellable);
+            yield sync_sent_mail(email, cancellable);
         }
 
         // Again, don't observe the cancellable here - if it's been
@@ -311,12 +311,12 @@ internal class Geary.Smtp.ClientService : Geary.ClientService {
         email_sent(rfc822);
     }
 
-    private async void save_sent_mail(Geary.Email email,
+    private async void save_sent_mail(Geary.Email message,
                                       GLib.Cancellable? cancellable)
         throws GLib.Error {
         Geary.FolderSupport.Create? create = (
             yield this.owner.get_required_special_folder_async(
-                Geary.SpecialFolderType.SENT, cancellable
+                SENT, cancellable
             )
         ) as Geary.FolderSupport.Create;
         if (create == null) {
@@ -325,12 +325,13 @@ internal class Geary.Smtp.ClientService : Geary.ClientService {
             );
         }
 
-        RFC822.Message message = email.get_message();
+        RFC822.Message raw = message.get_message();
         bool open = false;
         try {
-            yield create.open_async(Geary.Folder.OpenFlags.NO_DELAY, cancellable);
+            yield create.open_async(NO_DELAY, cancellable);
             open = true;
-            yield create.create_email_async(message, null, null, null, cancellable);
+            yield create.create_email_async(raw, null, null, null, cancellable);
+            yield wait_for_message(create, message, cancellable);
         } finally {
             if (open) {
                 try {
@@ -342,19 +343,17 @@ internal class Geary.Smtp.ClientService : Geary.ClientService {
         }
     }
 
-    private async void sync_sent_mail(GLib.Cancellable? cancellable)
+    private async void sync_sent_mail(Geary.Email message,
+                                      GLib.Cancellable? cancellable)
         throws GLib.Error {
-        Geary.Folder sent = yield this.owner.get_required_special_folder_async(
-            Geary.SpecialFolderType.SENT, cancellable
-        );
+        Geary.Folder sent = this.owner.get_special_folder(SENT);
         if (sent != null) {
             bool open = false;
             try {
-                yield sent.open_async(
-                    Geary.Folder.OpenFlags.NO_DELAY, cancellable
-                );
+                yield sent.open_async(NO_DELAY, cancellable);
                 open = true;
                 yield sent.synchronise_remote(cancellable);
+                yield wait_for_message(sent, message, cancellable);
             } finally {
                 if (open) {
                     try {
@@ -367,4 +366,36 @@ internal class Geary.Smtp.ClientService : Geary.ClientService {
             }
         }
     }
+
+    // Wait for a sent message to turn up. There's no guarantee how or
+    // when a server may make newly saved email show up, so poll for
+    // it. :(
+    private async void wait_for_message(Folder location,
+                                        Email sent,
+                                        GLib.Cancellable cancellable)
+        throws GLib.Error {
+        RFC822.MessageID? id = sent.message_id;
+        if (id != null) {
+            const int MAX_RETRIES = 3;
+            for (int i = 0; i < MAX_RETRIES; i++) {
+                Gee.List<Email>? list = yield location.list_email_by_id_async(
+                    null, 1, REFERENCES, NONE, cancellable
+                );
+                if (list != null && !list.is_empty) {
+                    Email listed = Collection.get_first<Email>(list);
+                    if (listed.message_id != null &&
+                        listed.message_id.equal_to(id)) {
+                        break;
+                    }
+                }
+
+                // Wait a second before retrying to give the server
+                // some breathing room
+                debug("Waiting for sent mail...");
+                GLib.Timeout.add_seconds(1, wait_for_message.callback);
+                yield;
+            }
+        }
+    }
+
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]