Merge branch 'wip/empty-folder-errors' into 'mainline'
Errors on emptying folders See merge request GNOME/geary!280
This commit is contained in:
commit
659a23f4e6
2 changed files with 63 additions and 17 deletions
|
|
@ -1230,10 +1230,14 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
|
|||
protected async void expunge_all_async(Cancellable? cancellable = null) throws Error {
|
||||
check_open("expunge_all_async");
|
||||
|
||||
EmptyFolder empty_folder = new EmptyFolder(this, cancellable);
|
||||
replay_queue.schedule(empty_folder);
|
||||
EmptyFolder op = new EmptyFolder(this, cancellable);
|
||||
this.replay_queue.schedule(op);
|
||||
yield op.wait_for_ready_async(cancellable);
|
||||
|
||||
yield empty_folder.wait_for_ready_async(cancellable);
|
||||
// Checkpoint the replay queue, so it and the folder remains
|
||||
// open while processing first the flag updates then the
|
||||
// expunge from the remote
|
||||
yield this.replay_queue.checkpoint(cancellable);
|
||||
}
|
||||
|
||||
private void check_open(string method) throws EngineError {
|
||||
|
|
|
|||
|
|
@ -60,6 +60,32 @@ private class Geary.ImapEngine.ReplayQueue : Geary.BaseObject {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private class WaitOperation : ReplayOperation {
|
||||
|
||||
public WaitOperation() {
|
||||
// LOCAL_AND_REMOTE to make sure this operation is flushed
|
||||
// all the way down the pipe
|
||||
base("Wait", LOCAL_AND_REMOTE, OnError.IGNORE_REMOTE);
|
||||
}
|
||||
|
||||
public override async ReplayOperation.Status replay_local_async()
|
||||
throws GLib.Error {
|
||||
return Status.CONTINUE;
|
||||
}
|
||||
|
||||
public override async void replay_remote_async(Imap.FolderSession remote)
|
||||
throws GLib.Error {
|
||||
// Noop
|
||||
}
|
||||
|
||||
public override string describe_state() {
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public int local_count { get {
|
||||
return local_queue.size;
|
||||
} }
|
||||
|
|
@ -230,23 +256,39 @@ private class Geary.ImapEngine.ReplayQueue : Geary.BaseObject {
|
|||
return true;
|
||||
}
|
||||
|
||||
private bool on_notification_timeout() {
|
||||
if (notification_queue.size == 0)
|
||||
return false;
|
||||
|
||||
debug("%s: Scheduling %d held server notification operations", owner.to_string(),
|
||||
notification_queue.size);
|
||||
|
||||
// no new operations in timeout span, add them all to the "real" queue
|
||||
foreach (ReplayOperation notification_op in notification_queue) {
|
||||
if (!schedule(notification_op)) {
|
||||
debug("Unable to schedule notification operation %s on %s", notification_op.to_string(),
|
||||
to_string());
|
||||
}
|
||||
/** Waits until all pending operations have been processed. */
|
||||
public async void checkpoint(GLib.Cancellable? cancellable)
|
||||
throws GLib.Error {
|
||||
WaitOperation wait_op = new WaitOperation();
|
||||
if (schedule(wait_op)) {
|
||||
yield wait_op.wait_for_ready_async(cancellable);
|
||||
} else {
|
||||
debug("Unable to schedule checkpoint op on %s", to_string());
|
||||
}
|
||||
}
|
||||
|
||||
notification_queue.clear();
|
||||
/** Queues for any pending server notifications to be processed. */
|
||||
public void flush_notifications() {
|
||||
if (this.notification_queue.size > 0) {
|
||||
debug("%s: Scheduling %d held server notification operations",
|
||||
this.owner.to_string(),
|
||||
this.notification_queue.size);
|
||||
|
||||
// no new operations in timeout span, add them all to the
|
||||
// "real" queue
|
||||
foreach (ReplayOperation notification_op in this.notification_queue) {
|
||||
if (!schedule(notification_op)) {
|
||||
debug("Unable to schedule notification operation %s on %s",
|
||||
notification_op.to_string(),
|
||||
to_string());
|
||||
}
|
||||
}
|
||||
this.notification_queue.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private bool on_notification_timeout() {
|
||||
flush_notifications();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue