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.
This commit is contained in:
parent
ee11d0d8ec
commit
6871c1cd90
5 changed files with 53 additions and 27 deletions
|
|
@ -60,5 +60,10 @@ public abstract class Geary.AbstractLocalFolder : Geary.Folder {
|
||||||
public override async void wait_for_close_async(Cancellable? cancellable = null) throws Error {
|
public override async void wait_for_close_async(Cancellable? cancellable = null) throws Error {
|
||||||
yield closed_semaphore.wait_async(cancellable);
|
yield closed_semaphore.wait_async(cancellable);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
public override async void synchronise_remote(GLib.Cancellable? cancellable)
|
||||||
|
throws GLib.Error {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -580,6 +580,19 @@ public abstract class Geary.Folder : BaseObject, Loggable {
|
||||||
*/
|
*/
|
||||||
public abstract async void wait_for_close_async(Cancellable? cancellable = null) throws Error;
|
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.
|
* List a number of contiguous emails in the folder's vector.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -114,12 +114,7 @@ private class Geary.ImapEngine.RefreshFolderSync : FolderOperation {
|
||||||
bool was_opened = false;
|
bool was_opened = false;
|
||||||
MinimalFolder minimal = (MinimalFolder) this.folder;
|
MinimalFolder minimal = (MinimalFolder) this.folder;
|
||||||
try {
|
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.open_async(Folder.OpenFlags.NO_DELAY, cancellable);
|
||||||
yield minimal.claim_remote_session(cancellable);
|
|
||||||
was_opened = true;
|
was_opened = true;
|
||||||
debug("Synchronising %s", minimal.to_string());
|
debug("Synchronising %s", minimal.to_string());
|
||||||
yield sync_folder(cancellable);
|
yield sync_folder(cancellable);
|
||||||
|
|
@ -169,24 +164,9 @@ private class Geary.ImapEngine.RefreshFolderSync : FolderOperation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual async void sync_folder(Cancellable cancellable)
|
protected virtual async void sync_folder(GLib.Cancellable cancellable)
|
||||||
throws Error {
|
throws GLib.Error {
|
||||||
yield wait_for_prefetcher(cancellable);
|
yield this.folder.synchronise_remote(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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -289,8 +269,9 @@ private class Geary.ImapEngine.CheckFolderSync : RefreshFolderSync {
|
||||||
next_epoch = prefetch_max_epoch.add_days(-1);
|
next_epoch = prefetch_max_epoch.add_days(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// let the prefetcher catch up
|
// Wait for basic syncing (i.e. the prefetcher) to
|
||||||
yield wait_for_prefetcher(cancellable);
|
// complete as well.
|
||||||
|
yield base.sync_folder(cancellable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,12 +65,12 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
|
||||||
internal ImapDB.Folder local_folder { get; private set; }
|
internal ImapDB.Folder local_folder { get; private set; }
|
||||||
|
|
||||||
internal ReplayQueue? replay_queue { get; private set; default = null; }
|
internal ReplayQueue? replay_queue { get; private set; default = null; }
|
||||||
internal EmailPrefetcher email_prefetcher { get; private set; }
|
|
||||||
internal ContactHarvester harvester { get; private set; }
|
internal ContactHarvester harvester { get; private set; }
|
||||||
|
|
||||||
private weak GenericAccount _account;
|
private weak GenericAccount _account;
|
||||||
private Geary.AggregatedFolderProperties _properties =
|
private Geary.AggregatedFolderProperties _properties =
|
||||||
new Geary.AggregatedFolderProperties(false, false);
|
new Geary.AggregatedFolderProperties(false, false);
|
||||||
|
private EmailPrefetcher email_prefetcher;
|
||||||
|
|
||||||
private int open_count = 0;
|
private int open_count = 0;
|
||||||
private Folder.OpenFlags open_flags = OpenFlags.NONE;
|
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);
|
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
|
// used by normalize_folders() during the normalization process; should not be used elsewhere
|
||||||
private async void detach_all_emails_async(Cancellable? cancellable) throws Error {
|
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,
|
Gee.List<Email>? all = yield local_folder.list_email_by_id_async(null, -1,
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,11 @@ public class Geary.MockFolder : Folder, MockObject {
|
||||||
throw new EngineError.UNSUPPORTED("Mock method");
|
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>?
|
public override async Gee.List<Geary.Email>?
|
||||||
list_email_by_id_async(Geary.EmailIdentifier? initial_id,
|
list_email_by_id_async(Geary.EmailIdentifier? initial_id,
|
||||||
int count,
|
int count,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue