Marking an email as read during item sync sometimes gets reverted by the sync
This issue is here as a brain dump of my recent investigation of the issue.
Precondition:
- IMAP server without
CONDSTORE
support - Large mailbox, slow internet connection or slow IMAP server
Scenario:
- User opens an IMAP folder in KMail.
- Sync of the folder is triggered by Akonadi.
- User marks a an existing message in the mailbox as read (appending
\Seen
flag). - The ItemSync completes.
Result: The state of the message that user has marked as read reverts back to unread.
Expected outcome: The message remains marked as read.
Cause:
When user marks an email as read in KMail, the change gets written to Akonadi and a change notification is dispatched to the IMAP resource. However, the resource is busy with ItemSync so it doesn't replay the change immediately. The IMAP resource still sees the message as "unread" because that's how it is on the IMAP server. If the server doesn't support CONDSTORE
it will list flags of all messages during sync, causing the user change to get overwritten in Akonadi. Once the Itemsync finishes and the flags change is replayed by the IMAP resource, message actually gets marked a read on the IMAP server. However, this won't generate any notification back to KMail.
Quick Solution: Abuse the "modified time" of Akonadi Item. During ItemSync, set mTime of all items to the timestamp at the beginning of the ItemSync. On the server, compare mTime of the synced Item with mTime stored in the database. If the item in the databse is newer, try to somehow merge flags (at least!).
Proper Solution:+ Server-side change recording. This would allow the Akonadi Server to check the pending changes during sync and detect whether there's a pending change for the item being currently synced and figure out how to merge the incoming state with the pending state so that the change in Akonadi is not lost.