[geary/wip/778276-better-flag-updates: 5/19] Modernise EmailPrefetcher a bit.
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/778276-better-flag-updates: 5/19] Modernise EmailPrefetcher a bit.
- Date: Tue, 5 Dec 2017 04:01:42 +0000 (UTC)
commit 76bc2b2750640353bec4c447dc23609e8b22303f
Author: Michael James Gratton <mike vee net>
Date: Mon Nov 20 20:19:57 2017 +1100
Modernise EmailPrefetcher a bit.
Not strictly necessary for this bug, but may as well since we're here.
* src/engine/imap-engine/imap-engine-email-prefetcher.vala
(EmailPrefetcher): Use a TimeoutManager and an explicit open and close
call from MinimalFolder.
.../imap-engine/imap-engine-email-prefetcher.vala | 107 ++++++++-----------
.../imap-engine/imap-engine-minimal-folder.vala | 27 +++--
2 files changed, 61 insertions(+), 73 deletions(-)
---
diff --git a/src/engine/imap-engine/imap-engine-email-prefetcher.vala
b/src/engine/imap-engine/imap-engine-email-prefetcher.vala
index 9a072fd..c46628e 100644
--- a/src/engine/imap-engine/imap-engine-email-prefetcher.vala
+++ b/src/engine/imap-engine/imap-engine-email-prefetcher.vala
@@ -21,60 +21,49 @@ private class Geary.ImapEngine.EmailPrefetcher : Object {
default = new Nonblocking.CountingSemaphore(null); }
private unowned ImapEngine.MinimalFolder folder;
- private int start_delay_sec;
private Nonblocking.Mutex mutex = new Nonblocking.Mutex();
private Gee.TreeSet<Geary.Email> prefetch_emails = new Gee.TreeSet<Geary.Email>(
Email.compare_recv_date_descending);
- private uint schedule_id = 0;
- private Cancellable cancellable = new Cancellable();
-
+ private TimeoutManager prefetch_timer;
+ private Cancellable? cancellable = null;
+
+
public EmailPrefetcher(ImapEngine.MinimalFolder folder, int start_delay_sec = PREFETCH_DELAY_SEC) {
- assert(start_delay_sec > 0);
-
this.folder = folder;
- this.start_delay_sec = start_delay_sec;
-
- folder.opened.connect(on_opened);
- folder.closed.connect(on_closed);
- folder.email_locally_appended.connect(on_local_expansion);
- folder.email_locally_inserted.connect(on_local_expansion);
- }
-
- ~EmailPrefetcher() {
- if (schedule_id != 0)
- message("Warning: Geary.EmailPrefetcher destroyed before folder closed");
-
- folder.opened.disconnect(on_opened);
- folder.closed.disconnect(on_closed);
- folder.email_locally_appended.disconnect(on_local_expansion);
- folder.email_locally_inserted.disconnect(on_local_expansion);
+
+ if (start_delay_sec <= 0) {
+ start_delay_sec = PREFETCH_DELAY_SEC;
+ }
+
+ this.prefetch_timer = new TimeoutManager.seconds(
+ start_delay_sec, () => { do_prefetch_async.begin(); }
+ );
}
-
- private void on_opened(Geary.Folder.OpenState open_state) {
- if (open_state != Geary.Folder.OpenState.BOTH)
- return;
-
- cancellable = new Cancellable();
-
+
+ public void open() {
+ this.cancellable = new Cancellable();
+
+ this.folder.email_locally_appended.connect(on_local_expansion);
+ this.folder.email_locally_inserted.connect(on_local_expansion);
+
// acquire here since .begin() only schedules for later
- active_sem.acquire();
- do_prepare_all_local_async.begin();
+ this.active_sem.acquire();
+ this.do_prepare_all_local_async.begin();
}
-
- private void on_closed(Geary.Folder.CloseReason close_reason) {
- // cancel for any reason ... this will be called multiple times, but the following operations
- // can be executed any number of times and still get the desired results
- cancellable.cancel();
-
- if (schedule_id != 0) {
- Source.remove(schedule_id);
- schedule_id = 0;
-
- // since an acquire was done when scheduled, need to notify when cancelled
- active_sem.blind_notify();
+
+ public void close() {
+ if (this.prefetch_timer.is_running) {
+ this.prefetch_timer.reset();
+ // since an acquire was done when scheduled, need to
+ // notify when cancelled
+ this.active_sem.blind_notify();
}
+
+ this.folder.email_locally_appended.disconnect(on_local_expansion);
+ this.folder.email_locally_inserted.disconnect(on_local_expansion);
+ this.cancellable = null;
}
-
+
private void on_local_expansion(Gee.Collection<Geary.EmailIdentifier> ids) {
// it's possible to be notified of an append prior to remote open; don't prefetch until
// that occurs
@@ -85,30 +74,24 @@ private class Geary.ImapEngine.EmailPrefetcher : Object {
active_sem.acquire();
do_prepare_new_async.begin(ids);
}
-
+
// emails should include PROPERTIES
private void schedule_prefetch(Gee.Collection<Geary.Email>? emails) {
if (emails == null || emails.size == 0)
return;
-
- debug("%s: scheduling %d emails for prefetching", folder.to_string(), emails.size);
-
- prefetch_emails.add_all(emails);
-
+
+ debug("%s: scheduling %d emails for prefetching",
+ folder.to_string(), emails.size);
+ this.prefetch_emails.add_all(emails);
+
// only increment active state if not rescheduling
- if (schedule_id != 0)
- Source.remove(schedule_id);
- else
- active_sem.acquire();
-
- schedule_id = Timeout.add_seconds(start_delay_sec, () => {
- schedule_id = 0;
- do_prefetch_async.begin();
-
- return false;
- });
+ if (!this.prefetch_timer.is_running) {
+ this.active_sem.acquire();
+ }
+
+ this.prefetch_timer.start();
}
-
+
private async void do_prepare_all_local_async() {
Gee.List<Geary.Email>? list = null;
try {
diff --git a/src/engine/imap-engine/imap-engine-minimal-folder.vala
b/src/engine/imap-engine/imap-engine-minimal-folder.vala
index a7423f3..5b90256 100644
--- a/src/engine/imap-engine/imap-engine-minimal-folder.vala
+++ b/src/engine/imap-engine/imap-engine-minimal-folder.vala
@@ -107,16 +107,15 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
);
this.local = local;
this.local_folder = local_folder;
- _special_folder_type = special_folder_type;
- _properties.add(local_folder.get_properties());
- replay_queue = new ReplayQueue(this);
-
+ this.local_folder.email_complete.connect(on_email_complete);
+
email_flag_watcher = new EmailFlagWatcher(this);
email_flag_watcher.email_flags_changed.connect(on_email_flags_changed);
-
- email_prefetcher = new EmailPrefetcher(this);
-
- local_folder.email_complete.connect(on_email_complete);
+
+ this._special_folder_type = special_folder_type;
+ this._properties.add(local_folder.get_properties());
+ this.replay_queue = new ReplayQueue(this);
+ this.email_prefetcher = new EmailPrefetcher(this);
// Notify now to ensure that wait_for_close_async does not
// block if never opened.
@@ -798,7 +797,10 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
}
_properties.add(remote_folder.properties);
-
+
+ // Now that the remote is open, update messages.
+ this.email_prefetcher.open();
+
// notify any subscribers with similar information
notify_opened(Geary.Folder.OpenState.BOTH, remote_count);
}
@@ -824,10 +826,13 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
// decrement open_count and, if zero, continue closing Folder
if (open_count == 0 || --open_count > 0)
return false;
-
+
+ // Close the prefetcher early so it stops using the remote ASAP
+ this.email_prefetcher.close();
+
if (remote_folder != null)
_properties.remove(remote_folder.properties);
-
+
// block anyone from wait_until_open_async(), as this is no longer open
remote_semaphore.reset();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]