[geary/gnome-43] engine: Cancel any remote folders update before marking a message
- From: Cédric Bellegarde <cbellegarde src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/gnome-43] engine: Cancel any remote folders update before marking a message
- Date: Mon, 26 Sep 2022 09:06:54 +0000 (UTC)
commit 0e6846cbf5d6d45f5b7f636f7a96119849182fd7
Author: Cédric Bellegarde <cedric bellegarde adishatz org>
Date: Thu Sep 22 11:49:05 2022 +0200
engine: Cancel any remote folders update before marking a message
When marking a message, a race condition can happen:
- A remote folders update is already running
- We mark the message locally and replay it remotely
- The previous remote update result restores invalid values locally
src/client/application/application-controller.vala | 2 ++
src/engine/api/geary-account.vala | 5 +++++
.../imap-engine/imap-engine-account-processor.vala | 20 ++++++++++++++++++++
.../imap-engine/imap-engine-generic-account.vala | 9 +++++++++
test/mock/mock-account.vala | 7 +++++++
5 files changed, 43 insertions(+)
---
diff --git a/src/client/application/application-controller.vala
b/src/client/application/application-controller.vala
index e6c5dfe46..1339a0342 100644
--- a/src/client/application/application-controller.vala
+++ b/src/client/application/application-controller.vala
@@ -2002,6 +2002,8 @@ private class Application.MarkEmailCommand : TrivialCommand, EmailCommand {
public override async void execute(GLib.Cancellable? cancellable)
throws GLib.Error {
+ this.location.account.cancel_remote_update();
+
yield this.store.mark_email_async(
this.email, this.to_add, this.to_remove, cancellable
);
diff --git a/src/engine/api/geary-account.vala b/src/engine/api/geary-account.vala
index 787fcbad9..4811f1051 100644
--- a/src/engine/api/geary-account.vala
+++ b/src/engine/api/geary-account.vala
@@ -309,6 +309,11 @@ public abstract class Geary.Account : BaseObject, Logging.Source {
*/
public abstract bool is_open();
+ /**
+ * Cancel any running/pending remote update for this {@link Account}.
+ */
+ public abstract void cancel_remote_update();
+
/**
* Rebuild the local data stores for this {@link Account}.
*
diff --git a/src/engine/imap-engine/imap-engine-account-processor.vala
b/src/engine/imap-engine/imap-engine-account-processor.vala
index 0e5cc2f02..1fc08f9d9 100644
--- a/src/engine/imap-engine/imap-engine-account-processor.vala
+++ b/src/engine/imap-engine/imap-engine-account-processor.vala
@@ -78,6 +78,26 @@ internal class Geary.ImapEngine.AccountProcessor :
this.queue.revoke(op);
}
+ // Revokes all operations with the given type; returns true if at least one
+ // operation with the given type was found
+ public bool dequeue_by_type(GLib.Type type) {
+ bool found = false;
+ if (this.current_op != null &&
+ this.current_op.get_type() == type &&
+ this.op_cancellable != null) {
+ this.op_cancellable.cancel();
+ this.op_cancellable = null;
+ found = true;
+ }
+ this.queue.revoke_matching((op) => {
+ if (op.get_type() == type) {
+ found = true;
+ }
+ return op.get_type() == type;
+ });
+ return found;
+ }
+
public void stop() {
this.is_running = false;
if (this.op_cancellable != null) {
diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala
b/src/engine/imap-engine/imap-engine-generic-account.vala
index a459274b6..2db971640 100644
--- a/src/engine/imap-engine/imap-engine-generic-account.vala
+++ b/src/engine/imap-engine/imap-engine-generic-account.vala
@@ -229,6 +229,15 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
return open;
}
+ /** {@inheritDoc} */
+ public override void cancel_remote_update() {
+ // Cancel and update again
+ if (this.processor.dequeue_by_type(typeof(UpdateRemoteFolders))) {
+ debug("Cancelled a remote update! Updating again...\n");
+ update_remote_folders(false);
+ }
+ }
+
public override async void rebuild_async(GLib.Cancellable? cancellable = null)
throws GLib.Error {
if (this.open) {
diff --git a/test/mock/mock-account.vala b/test/mock/mock-account.vala
index f617f9693..ceee35ef6 100644
--- a/test/mock/mock-account.vala
+++ b/test/mock/mock-account.vala
@@ -58,6 +58,13 @@ public class Mock.Account : Geary.Account,
}
}
+ public override void cancel_remote_update() {
+ try {
+ void_call("cancel_remote_update", {});
+ } catch (GLib.Error err) {
+ }
+ }
+
public override async void rebuild_async(GLib.Cancellable? cancellable = null)
throws GLib.Error {
void_call("rebuild_async", { cancellable });
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]