[geary/wip/131-sent-mail: 13/18] Make remote folder synchronisation a top-level API method
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/131-sent-mail: 13/18] Make remote folder synchronisation a top-level API method
- Date: Sun, 11 Aug 2019 22:47:31 +0000 (UTC)
commit 3634879b9d3ff9458d078cb6b022707d25964ee5
Author: Michael Gratton <mike vee net>
Date: Thu Aug 8 23:00:42 2019 +1000
Make remote folder synchronisation a top-level API method
Add Geary.Folder::synchronise_remote method to allow clients to
explicitly check for new mail in a folder. Move code from
ImapEngine.AccountSynchronizer as the basic implementation, but also
ensure pending replay queue notifications are processed before the
process is complete.
src/engine/api/geary-abstract-local-folder.vala | 7 ++++-
src/engine/api/geary-folder.vala | 13 +++++++++
.../imap-engine-account-synchronizer.vala | 31 +++++-----------------
.../imap-engine/imap-engine-minimal-folder.vala | 24 ++++++++++++++++-
test/engine/api/geary-folder-mock.vala | 5 ++++
5 files changed, 53 insertions(+), 27 deletions(-)
---
diff --git a/src/engine/api/geary-abstract-local-folder.vala b/src/engine/api/geary-abstract-local-folder.vala
index afc3fe7a..e8217328 100644
--- a/src/engine/api/geary-abstract-local-folder.vala
+++ b/src/engine/api/geary-abstract-local-folder.vala
@@ -60,5 +60,10 @@ public abstract class Geary.AbstractLocalFolder : Geary.Folder {
public override async void wait_for_close_async(Cancellable? cancellable = null) throws Error {
yield closed_semaphore.wait_async(cancellable);
}
-}
+ public override async void synchronise_remote(GLib.Cancellable? cancellable)
+ throws GLib.Error {
+ // No-op
+ }
+
+}
diff --git a/src/engine/api/geary-folder.vala b/src/engine/api/geary-folder.vala
index 948b925f..a7f4d7fe 100644
--- a/src/engine/api/geary-folder.vala
+++ b/src/engine/api/geary-folder.vala
@@ -580,6 +580,19 @@ public abstract class Geary.Folder : BaseObject, Loggable {
*/
public abstract async void wait_for_close_async(Cancellable? cancellable = null) throws Error;
+ /**
+ * Synchronises the local folder with the remote mailbox.
+ *
+ * If backed by a remote folder, this ensures that the end of the
+ * vector is up to date with the end of the remote mailbox, and
+ * that all messages in the vector satisfy the minimum
+ * requirements for being used by the engine.
+ *
+ * The folder must be opened prior to attempting this operation.
+ */
+ public abstract async void synchronise_remote(GLib.Cancellable? cancellable)
+ throws GLib.Error;
+
/**
* List a number of contiguous emails in the folder's vector.
*
diff --git a/src/engine/imap-engine/imap-engine-account-synchronizer.vala
b/src/engine/imap-engine/imap-engine-account-synchronizer.vala
index c28ca396..80ad51ed 100644
--- a/src/engine/imap-engine/imap-engine-account-synchronizer.vala
+++ b/src/engine/imap-engine/imap-engine-account-synchronizer.vala
@@ -114,12 +114,7 @@ private class Geary.ImapEngine.RefreshFolderSync : FolderOperation {
bool was_opened = false;
MinimalFolder minimal = (MinimalFolder) this.folder;
try {
- // Open the folder on no delay since there's no point just
- // waiting around for it. Then claim a remote session so
- // we know that a remote connection has been made and the
- // folder has had a chance to normalise itself.
yield minimal.open_async(Folder.OpenFlags.NO_DELAY, cancellable);
- yield minimal.claim_remote_session(cancellable);
was_opened = true;
debug("Synchronising %s", minimal.to_string());
yield sync_folder(cancellable);
@@ -169,24 +164,9 @@ private class Geary.ImapEngine.RefreshFolderSync : FolderOperation {
}
}
- protected virtual async void sync_folder(Cancellable cancellable)
- throws Error {
- yield wait_for_prefetcher(cancellable);
- }
-
- protected async void wait_for_prefetcher(Cancellable cancellable)
- throws Error {
- MinimalFolder minimal = (MinimalFolder) this.folder;
- try {
- yield minimal.email_prefetcher.active_sem.wait_async(cancellable);
- } catch (Error err) {
- Logging.debug(
- Logging.Flag.PERIODIC,
- "Error waiting for email prefetcher to complete %s: %s",
- folder.to_string(),
- err.message
- );
- }
+ protected virtual async void sync_folder(GLib.Cancellable cancellable)
+ throws GLib.Error {
+ yield this.folder.synchronise_remote(cancellable);
}
}
@@ -289,8 +269,9 @@ private class Geary.ImapEngine.CheckFolderSync : RefreshFolderSync {
next_epoch = prefetch_max_epoch.add_days(-1);
}
- // let the prefetcher catch up
- yield wait_for_prefetcher(cancellable);
+ // Wait for basic syncing (i.e. the prefetcher) to
+ // complete as well.
+ yield base.sync_folder(cancellable);
}
}
diff --git a/src/engine/imap-engine/imap-engine-minimal-folder.vala
b/src/engine/imap-engine/imap-engine-minimal-folder.vala
index b450f4ec..a49f4596 100644
--- a/src/engine/imap-engine/imap-engine-minimal-folder.vala
+++ b/src/engine/imap-engine/imap-engine-minimal-folder.vala
@@ -65,12 +65,12 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
internal ImapDB.Folder local_folder { get; private set; }
internal ReplayQueue? replay_queue { get; private set; default = null; }
- internal EmailPrefetcher email_prefetcher { get; private set; }
internal ContactHarvester harvester { get; private set; }
private weak GenericAccount _account;
private Geary.AggregatedFolderProperties _properties =
new Geary.AggregatedFolderProperties(false, false);
+ private EmailPrefetcher email_prefetcher;
private int open_count = 0;
private Folder.OpenFlags open_flags = OpenFlags.NONE;
@@ -278,6 +278,28 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
yield this.closed_semaphore.wait_async(cancellable);
}
+ /** {@inheritDoc} */
+ public override async void synchronise_remote(GLib.Cancellable? cancellable)
+ throws GLib.Error {
+ check_open("synchronise_remote");
+ // The normalisation process will pick up any missing messages
+ // if closed so ensure there is a remote session
+ Imap.FolderSession remote = yield claim_remote_session(cancellable);
+
+ // Send a NOOP so the server can return an untagged EXISTS if
+ // any new messages have arrived since the remote was opened.
+ yield remote.send_noop(cancellable);
+
+ // Wait until the replay queue has processed all notifications
+ // so the prefetcher becomes aware of the new mail
+ this.replay_queue.flush_notifications();
+ yield this.replay_queue.checkpoint(cancellable);
+
+ // Finally, wait for the prefetcher to have finished
+ // downloading the new mail.
+ yield this.email_prefetcher.active_sem.wait_async(cancellable);
+ }
+
// used by normalize_folders() during the normalization process; should not be used elsewhere
private async void detach_all_emails_async(Cancellable? cancellable) throws Error {
Gee.List<Email>? all = yield local_folder.list_email_by_id_async(null, -1,
diff --git a/test/engine/api/geary-folder-mock.vala b/test/engine/api/geary-folder-mock.vala
index e663341a..29856044 100644
--- a/test/engine/api/geary-folder-mock.vala
+++ b/test/engine/api/geary-folder-mock.vala
@@ -78,6 +78,11 @@ public class Geary.MockFolder : Folder, MockObject {
throw new EngineError.UNSUPPORTED("Mock method");
}
+ public override async void synchronise_remote(GLib.Cancellable? cancellable)
+ throws GLib.Error {
+ void_call("synchronise_remote", { cancellable });
+ }
+
public override async Gee.List<Geary.Email>?
list_email_by_id_async(Geary.EmailIdentifier? initial_id,
int count,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]