[geary/mjog/replay-queue-fixes: 1/2] Geary.ImapEngine: Ensure actual replay ops interleave correctly
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/mjog/replay-queue-fixes: 1/2] Geary.ImapEngine: Ensure actual replay ops interleave correctly
- Date: Wed, 24 Feb 2021 08:10:04 +0000 (UTC)
commit 224dbf08d33a7b3590623a9d1141cb0d3f4b23df
Author: Michael Gratton <mike vee net>
Date: Tue Feb 23 22:55:20 2021 +1100
Geary.ImapEngine: Ensure actual replay ops interleave correctly
Ensure `ReplayAppend`, `ReplayUpdate` and `ReplayRemoval` ops all
run as remote-only ops, so that they can't be incorrectly interleaved.
For example an update queued after a remove can't be executed first
in the local queue.
.../imap-engine/replay-ops/imap-engine-replay-append.vala | 7 +++++--
.../imap-engine/replay-ops/imap-engine-replay-removal.vala | 13 +++++--------
.../imap-engine/replay-ops/imap-engine-replay-update.vala | 11 ++++++-----
3 files changed, 16 insertions(+), 15 deletions(-)
---
diff --git a/src/engine/imap-engine/replay-ops/imap-engine-replay-append.vala
b/src/engine/imap-engine/replay-ops/imap-engine-replay-append.vala
index 2ed094388..720ca0c0e 100644
--- a/src/engine/imap-engine/replay-ops/imap-engine-replay-append.vala
+++ b/src/engine/imap-engine/replay-ops/imap-engine-replay-append.vala
@@ -20,8 +20,11 @@ private class Geary.ImapEngine.ReplayAppend : Geary.ImapEngine.ReplayOperation {
int remote_count,
Gee.List<Imap.SequenceNumber> positions,
Cancellable? cancellable) {
- // IGNORE remote errors because the reconnect will re-normalize the folder, making this
- // append moot
+ // Since this is a report op, both ReplayRemove and
+ // ReplayUpdate must also be run as remote ops so their
+ // effects are interleaved correctly. IGNORE remote errors
+ // because the reconnect will re-normalize the folder, making
+ // this append moot
base ("Append", Scope.REMOTE_ONLY, OnError.IGNORE_REMOTE);
this.owner = owner;
diff --git a/src/engine/imap-engine/replay-ops/imap-engine-replay-removal.vala
b/src/engine/imap-engine/replay-ops/imap-engine-replay-removal.vala
index 6b8a0b8a3..60f186e1b 100644
--- a/src/engine/imap-engine/replay-ops/imap-engine-replay-removal.vala
+++ b/src/engine/imap-engine/replay-ops/imap-engine-replay-removal.vala
@@ -16,8 +16,11 @@ private class Geary.ImapEngine.ReplayRemoval : Geary.ImapEngine.ReplayOperation
public ReplayRemoval(MinimalFolder owner, int remote_count, Imap.SequenceNumber position) {
- // remote error will cause folder to reconnect and re-normalize, making this remove moot
- base ("Removal", Scope.LOCAL_AND_REMOTE, OnError.IGNORE_REMOTE);
+ // Although technically a local-only operation, must treat as
+ // remote to ensure it's processed in-order with ReplayAppend
+ // and ReplayUpdate operations. Remote error will cause folder
+ // to reconnect and re-normalize, making this remove moot
+ base ("Removal", Scope.REMOTE_ONLY, OnError.IGNORE_REMOTE);
this.owner = owner;
this.remote_count = remote_count;
@@ -37,12 +40,6 @@ private class Geary.ImapEngine.ReplayRemoval : Geary.ImapEngine.ReplayOperation
// this ReplayOperation doesn't do remote removes, it reacts to them
}
- public override async ReplayOperation.Status replay_local_async() throws Error {
- // Although technically a local-only operation, must treat as remote to ensure it's
- // processed in-order with ReplayAppend operations
- return ReplayOperation.Status.CONTINUE;
- }
-
public override async void replay_remote_async(Imap.FolderSession remote)
throws GLib.Error {
debug("%s: ReplayRemoval this.position=%s reported_remote_count=%d",
diff --git a/src/engine/imap-engine/replay-ops/imap-engine-replay-update.vala
b/src/engine/imap-engine/replay-ops/imap-engine-replay-update.vala
index eb0bc3e7f..beb573553 100644
--- a/src/engine/imap-engine/replay-ops/imap-engine-replay-update.vala
+++ b/src/engine/imap-engine/replay-ops/imap-engine-replay-update.vala
@@ -22,7 +22,10 @@ private class Geary.ImapEngine.ReplayUpdate : Geary.ImapEngine.ReplayOperation {
int remote_count,
Imap.SequenceNumber position,
Imap.FetchedData data) {
- base ("Update", Scope.LOCAL_ONLY, OnError.RETRY);
+ // Although technically a local-only operation, must treat as
+ // remote to ensure it's processed in-order with ReplayAppend
+ // and ReplayRemove operations
+ base ("Update", Scope.REMOTE_ONLY, OnError.RETRY);
this.owner = owner;
this.remote_count = remote_count;
@@ -30,8 +33,8 @@ private class Geary.ImapEngine.ReplayUpdate : Geary.ImapEngine.ReplayOperation {
this.data = data;
}
- public override async ReplayOperation.Status replay_local_async()
- throws Error {
+ public override async void replay_remote_async(Imap.FolderSession remote)
+ throws GLib.Error {
Imap.MessageFlags? message_flags =
this.data.data_map.get(Imap.FetchDataSpecifier.FLAGS) as Imap.MessageFlags;
if (message_flags != null) {
@@ -66,8 +69,6 @@ private class Geary.ImapEngine.ReplayUpdate : Geary.ImapEngine.ReplayOperation {
debug("%s Don't know what to do without any FLAGS: %s",
to_string(), this.data.to_string());
}
-
- return ReplayOperation.Status.COMPLETED;
}
public override string describe_state() {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]