[geary/wip/save-sent-713263] Implement "failsafe" pushing up to sent mail



commit d8b6df666692692c8b736cc992ae258039015c81
Author: Charles Lindsay <chaz yorba org>
Date:   Thu Jan 23 17:29:37 2014 -0800

    Implement "failsafe" pushing up to sent mail

 src/engine/imap-db/outbox/smtp-outbox-folder.vala |   77 ++++++++++++++-------
 1 files changed, 53 insertions(+), 24 deletions(-)
---
diff --git a/src/engine/imap-db/outbox/smtp-outbox-folder.vala 
b/src/engine/imap-db/outbox/smtp-outbox-folder.vala
index e92c8ae..8fa3e2e 100644
--- a/src/engine/imap-db/outbox/smtp-outbox-folder.vala
+++ b/src/engine/imap-db/outbox/smtp-outbox-folder.vala
@@ -178,9 +178,9 @@ private class Geary.SmtpOutboxFolder : Geary.AbstractLocalFolder, Geary.FolderSu
             try {
                 row = yield outbox_queue.recv_async();
                 
-                // Ignore messages that have since been deleted.
-                if (!yield ordering_exists_async(row.ordering, null)) {
-                    debug("Dropping deleted outbox message %s", row.outbox_id.to_string());
+                // Ignore messages that have since been sent.
+                if (!yield is_unsent_async(row.ordering, null)) {
+                    debug("Dropping sent outbox message %s", row.outbox_id.to_string());
                     continue;
                 }
             } catch (Error wait_err) {
@@ -238,7 +238,7 @@ private class Geary.SmtpOutboxFolder : Geary.AbstractLocalFolder, Geary.FolderSu
                             CredentialsMediator.ServiceFlag.SMTP, true))
                             report = false;
                     } catch (Error e) {
-                        debug("Error prompting for IMAP password: %s", e.message);
+                        debug("Error prompting for SMTP password: %s", e.message);
                     }
                     
                     if (report)
@@ -257,20 +257,40 @@ private class Geary.SmtpOutboxFolder : Geary.AbstractLocalFolder, Geary.FolderSu
                 continue;
             }
             
+            // If we got this far the send was successful, so reset the send retry interval.
+            send_retry_seconds = MIN_SEND_RETRY_INTERVAL_SEC;
+            
+            if (_account.information.allow_save_sent_mail() && _account.information.save_sent_mail) {
+                // First mark as sent, so if there's a problem pushing up to Sent Mail,
+                // we don't retry sending.
+                try {
+                    debug("Outbox postman: Marking %s as sent", row.outbox_id.to_string());
+                    yield mark_email_as_sent_async(row.outbox_id, null);
+                } catch (Error e) {
+                    debug("Outbox postman: Unable to mark row as sent: %s", e.message);
+                }
+                
+                try {
+                    debug("Outbox postman: Saving %s to sent mail", row.outbox_id.to_string());
+                    yield save_sent_email_async(message, null);
+                } catch (Error e) {
+                    debug("Outbox postman: Error saving sent email: %s", e.message);
+                    report_problem(Geary.Account.Problem.SAVE_SENT_EMAIL_FAILED, e);
+                    
+                    continue;
+                }
+            }
+            
             // Remove from database ... can't use remove_email_async() because this runs even if
             // the outbox is closed as a Geary.Folder.
             try {
-                debug("Outbox postman: Removing \"%s\" (ID:%s) from database", message_subject(message),
-                    row.outbox_id.to_string());
+                debug("Outbox postman: Deleting row %s", row.outbox_id.to_string());
                 Gee.ArrayList<SmtpOutboxEmailIdentifier> list = new 
Gee.ArrayList<SmtpOutboxEmailIdentifier>();
                 list.add(row.outbox_id);
                 yield internal_remove_email_async(list, null);
-            } catch (Error rm_err) {
-                debug("Outbox postman: Unable to remove row from database: %s", rm_err.message);
+            } catch (Error e) {
+                debug("Outbox postman: Unable to delete row: %s", e.message);
             }
-            
-            // If we got this far the send was successful, so reset the send retry interval.
-            send_retry_seconds = MIN_SEND_RETRY_INTERVAL_SEC;
         }
         
         debug("Exiting outbox postman");
@@ -494,7 +514,18 @@ private class Geary.SmtpOutboxFolder : Geary.AbstractLocalFolder, Geary.FolderSu
         return row_to_email(row);
     }
     
-    public virtual async void remove_email_async(Gee.List<Geary.EmailIdentifier> email_ids, 
+    private async void mark_email_as_sent_async(SmtpOutboxEmailIdentifier outbox_id,
+        Cancellable? cancellable = null) throws Error {
+        yield db.exec_transaction_async(Db.TransactionType.WR, (cx) => {
+            do_mark_email_as_sent(cx, outbox_id, cancellable);
+            
+            // TODO: also update the Geary.Email objects' flags with Geary.EmailFlags.OUTBOX_SENT.
+            
+            return Db.TransactionOutcome.COMMIT;
+        }, cancellable);
+    }
+    
+    public virtual async void remove_email_async(Gee.List<Geary.EmailIdentifier> email_ids,
         Cancellable? cancellable = null) throws Error {
         check_open();
         
@@ -595,20 +626,10 @@ private class Geary.SmtpOutboxFolder : Geary.AbstractLocalFolder, Geary.FolderSu
             throw smtp_err;
         
         email_sent(rfc822);
-        
-        try {
-            yield save_sent_email_async(rfc822, cancellable);
-        } catch (Error e) {
-            debug("Error saving sent email: %s", e.message);
-            report_problem(Geary.Account.Problem.SAVE_SENT_EMAIL_FAILED, e);
-        }
     }
     
     private async void save_sent_email_async(Geary.RFC822.Message rfc822, Cancellable? cancellable)
         throws Error {
-        if (!_account.information.allow_save_sent_mail() || !_account.information.save_sent_mail)
-            return;
-        
         Geary.Folder? sent_mail = _account.get_special_folder(Geary.SpecialFolderType.SENT);
         Geary.FolderSupport.Create? create = sent_mail as Geary.FolderSupport.Create;
         if (create == null)
@@ -637,11 +658,11 @@ private class Geary.SmtpOutboxFolder : Geary.AbstractLocalFolder, Geary.FolderSu
         }
     }
     
-    private async bool ordering_exists_async(int64 ordering, Cancellable? cancellable) throws Error {
+    private async bool is_unsent_async(int64 ordering, Cancellable? cancellable) throws Error {
         bool exists = false;
         yield db.exec_transaction_async(Db.TransactionType.RO, (cx) => {
             Db.Statement stmt = cx.prepare(
-                "SELECT 1 FROM SmtpOutboxTable WHERE ordering=?");
+                "SELECT 1 FROM SmtpOutboxTable WHERE ordering=? AND sent = 0");
             stmt.bind_int64(0, ordering);
             
             exists = !stmt.exec(cancellable).finished;
@@ -718,6 +739,14 @@ private class Geary.SmtpOutboxFolder : Geary.AbstractLocalFolder, Geary.FolderSu
             results.string_buffer_at(1), _path);
     }
     
+    private void do_mark_email_as_sent(Db.Connection cx, SmtpOutboxEmailIdentifier id, Cancellable? 
cancellable)
+        throws Error {
+        Db.Statement stmt = cx.prepare("UPDATE SmtpOutboxTable SET sent = 1 WHERE ordering = ?");
+        stmt.bind_int64(0, id.ordering);
+        
+        stmt.exec(cancellable);
+    }
+    
     private bool do_remove_email(Db.Connection cx, SmtpOutboxEmailIdentifier id, Cancellable? cancellable)
         throws Error {
         Db.Statement stmt = cx.prepare("DELETE FROM SmtpOutboxTable WHERE ordering=?");


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