diff options
author | Christoph Wurst <christoph@winzerhof-wurst.at> | 2020-04-28 08:55:11 +0300 |
---|---|---|
committer | Christoph Wurst <christoph@winzerhof-wurst.at> | 2020-04-28 09:04:25 +0300 |
commit | 6bdb866ca9bbc13b89765c8c6a7af0bfb1aa5cf2 (patch) | |
tree | ba3c060b04e00068ee1e150190e15c4b2780e37a /lib/IMAP | |
parent | f63a85180218bf1a5f66620c5f96cc633a9a15a1 (diff) |
Fix endless initial sync due to empty partial page
The initial message cache sync estimates the UID range of the next
message page so it can fetch messages efficiently. There was an
uncovered edge case where the next page might not return any message,
simple because there is a larger gap between the existing UIDs.
Therefore the sync process was aborted as incomplete over and over as it
could not make any progress and the number of known messages never
reached the total number of messages on IMAP. This patch changes the
logic so it retries the next page if the current one is empty. To break
a possibly infinite recursion there is a check about reaching the
highest UID reported by the server.
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
Diffstat (limited to 'lib/IMAP')
-rw-r--r-- | lib/IMAP/MessageMapper.php | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/lib/IMAP/MessageMapper.php b/lib/IMAP/MessageMapper.php index 8389e3b52..756cb79ff 100644 --- a/lib/IMAP/MessageMapper.php +++ b/lib/IMAP/MessageMapper.php @@ -140,19 +140,32 @@ class MessageMapper { $query = new Horde_Imap_Client_Fetch_Query(); $query->uid(); + $fetchResult = $client->fetch( + $mailbox, + $query, + [ + 'ids' => new Horde_Imap_Client_Ids($lower . ':' . $upper) + ] + ); + if (count($fetchResult) === 0 && $upper < $max) { + /* + * There were no messages in this range, but we've not reached the + * latest message. This means we should try again until there is a + * page that actually returns at least one message + * + * We take $upper as the lowest known UID as we just found out that + * there is nothing to fetch in $highestKnownUid:$upper + */ + $this->logger->debug("Range for findAll did not find any messages. Trying again with a succeeding range"); + return $this->findAll($client, $mailbox, $maxResults, $upper); + } $uidsToFetch = array_slice( array_filter( array_map( function (Horde_Imap_Client_Data_Fetch $data) { return $data->getUid(); }, - iterator_to_array($client->fetch( - $mailbox, - $query, - [ - 'ids' => new Horde_Imap_Client_Ids($lower . ':' . $upper) - ] - )) + iterator_to_array($fetchResult) ), function (int $uid) use ($highestKnownUid) { |