[geary: 14/66] Trigger idle cleanup per account when backgrounded



commit 609ee01e3e04c0e3b43acbed2cc8fcf5346b4660
Author: Chris Heywood <15127-creywood users noreply gitlab gnome org>
Date:   Wed Jan 8 14:08:52 2020 +0100

    Trigger idle cleanup per account when backgrounded
    
    Also handle continuation of cleanup after old messages have been
    detached. Flagged vacuuming is performed even when the cleanup
    interval hasn't been reached. The tracking of last background
    cleanup time in Account.Information is possibly temporary and isn't
    yet persisted.

 src/client/application/application-controller.vala |  2 ++
 src/engine/api/geary-account-information.vala      |  1 +
 src/engine/api/geary-account.vala                  |  8 +++++
 .../imap-engine/imap-engine-generic-account.vala   | 36 ++++++++++++++++++++++
 test/engine/api/geary-account-mock.vala            |  3 ++
 5 files changed, 50 insertions(+)
---
diff --git a/src/client/application/application-controller.vala 
b/src/client/application/application-controller.vala
index 9f98f091b..cfb7d1867 100644
--- a/src/client/application/application-controller.vala
+++ b/src/client/application/application-controller.vala
@@ -1418,6 +1418,8 @@ internal class Application.Controller : Geary.BaseObject {
 
         debug("Checking for backgrounded idle work");
         foreach (AccountContext context in this.accounts.values) {
+            Geary.Account account = context.account;
+            account.app_backgrounded_cleanup.begin(context.cancellable);
         }
     }
 
diff --git a/src/engine/api/geary-account-information.vala b/src/engine/api/geary-account-information.vala
index cdc05eb6f..60c42e7ab 100644
--- a/src/engine/api/geary-account-information.vala
+++ b/src/engine/api/geary-account-information.vala
@@ -210,6 +210,7 @@ public class Geary.AccountInformation : BaseObject {
         default = new Gee.LinkedList<Geary.RFC822.MailboxAddress>();
     }
 
+    public DateTime? last_backgrounded_cleanup_time { get; set; default = null; }
 
     /**
      * Emitted when a service has reported an authentication failure.
diff --git a/src/engine/api/geary-account.vala b/src/engine/api/geary-account.vala
index 30bb1d1ba..d9100c1cf 100644
--- a/src/engine/api/geary-account.vala
+++ b/src/engine/api/geary-account.vala
@@ -507,6 +507,14 @@ public abstract class Geary.Account : BaseObject, Logging.Source {
         return new Logging.State(this, this.information.id);
     }
 
+    /**
+     * Run account cleanup work if the appropriate interval has past since
+     * last execution. Alternatively if the interval has not past but vacuum
+     * GC has been flagged to run this will be executed. Designed to be run
+     * while the app is in the background and idle.
+     */
+    public abstract async void app_backgrounded_cleanup(Cancellable? cancellable);
+
     /** Fires a {@link opened} signal. */
     protected virtual void notify_opened() {
         opened();
diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala 
b/src/engine/imap-engine/imap-engine-generic-account.vala
index 0cfc9ae15..a8b8a68cb 100644
--- a/src/engine/imap-engine/imap-engine-generic-account.vala
+++ b/src/engine/imap-engine/imap-engine-generic-account.vala
@@ -17,6 +17,10 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
     // we don't need to double check.
     private const int REFRESH_FOLDER_LIST_SEC = 15 * 60;
 
+    // Frequency of account cleanup work, performed when idle with the app
+    // backgrounded
+    private const uint APP_BACKGROUNDED_CLEANUP_WORK_INTERVAL_MINUTES = 60 * 24;
+
     private const Geary.SpecialFolderType[] SUPPORTED_SPECIAL_FOLDERS = {
         Geary.SpecialFolderType.DRAFTS,
         Geary.SpecialFolderType.SENT,
@@ -39,6 +43,8 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
     /** Local database for the account. */
     public ImapDB.Account local { get; private set; }
 
+    public signal void old_messages_background_cleanup_request(Cancellable? cancellable);
+
     private bool open = false;
     private Cancellable? open_cancellable = null;
     private Nonblocking.Semaphore? remote_ready_lock = null;
@@ -524,6 +530,36 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
         return (map.size == 0) ? null : map;
     }
 
+    /** {@inheritDoc} */
+    public override async void app_backgrounded_cleanup(Cancellable? cancellable) {
+        debug("Backgrounded cleanup check for %s account", this.information.display_name);
+
+        DateTime now = new DateTime.now_local();
+        DateTime? last_cleanup = this.information.last_backgrounded_cleanup_time;
+
+        if (last_cleanup == null ||
+            (now.difference(last_cleanup) / TimeSpan.MINUTE > 
APP_BACKGROUNDED_CLEANUP_WORK_INTERVAL_MINUTES)) {
+            // Interval check is OK, start by detaching old messages
+            this.information.last_backgrounded_cleanup_time = now;
+            this.old_messages_background_cleanup_request(cancellable);
+        } else if (local.db.want_background_vacuum) {
+            // Vacuum has been flagged as needed, run it
+            local.db.run_gc.begin(cancellable, false, this);
+        }
+    }
+
+    // Continue backgrounded app cleanup work after the first phase,
+    // old message detachment, has completed
+    public void app_backgrounded_cleanup_continued(bool messages_detached, Cancellable? cancellable) {
+        if (messages_detached) {
+            // Kick off GC, forcing reap as we've removed messages, allowing vacuum
+            local.db.run_gc.begin(cancellable, true, this);
+        } else {
+            // Kick off GC, allowing vacuum
+            local.db.run_gc.begin(cancellable, false, this);
+        }
+    }
+
     /**
      * Constructs a set of folders and adds them to the account.
      *
diff --git a/test/engine/api/geary-account-mock.vala b/test/engine/api/geary-account-mock.vala
index 9f074d62b..77ca82877 100644
--- a/test/engine/api/geary-account-mock.vala
+++ b/test/engine/api/geary-account-mock.vala
@@ -274,4 +274,7 @@ public class Geary.MockAccount : Account, MockObject {
         );
     }
 
+    public override async void app_backgrounded_cleanup(Cancellable? cancellable) {
+
+    }
 }


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