Skip to content

Commit 74f0f20

Browse files
fix: Drop current folder if we have too many changes (#1762)
2 parents 6a4a287 + 2f52b94 commit 74f0f20

File tree

4 files changed

+54
-1
lines changed

4 files changed

+54
-1
lines changed

MailCore/Cache/MailboxManager/MailboxManager+Thread.swift

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,14 @@ public extension MailboxManager {
8787
let newCursor: String
8888

8989
if let previousCursor {
90-
newCursor = try await getMessagesDelta(signature: previousCursor, folder: folder)
90+
do {
91+
newCursor = try await getMessagesDelta(signature: previousCursor, folder: folder)
92+
} catch ErrorDomain.tooManyDiffs {
93+
try await resetFolder(folder)
94+
95+
// fetch folder as if we had no cursor
96+
newCursor = try await fetchOldMessagesUids(folder: folder)
97+
}
9198
} else {
9299
newCursor = try await fetchOldMessagesUids(folder: folder)
93100
}
@@ -161,6 +168,9 @@ public extension MailboxManager {
161168
folderId: folder.remoteId,
162169
signature: signature
163170
)
171+
172+
try messagesDelta.ensureValidDelta()
173+
164174
await handleDelta(messagesDelta: messagesDelta, folder: folder)
165175

166176
return messagesDelta.cursor
@@ -170,6 +180,9 @@ public extension MailboxManager {
170180
folderId: folder.remoteId,
171181
signature: signature
172182
)
183+
184+
try messagesDelta.ensureValidDelta()
185+
173186
await handleDelta(messagesDelta: messagesDelta, folder: folder)
174187

175188
return messagesDelta.cursor
@@ -591,6 +604,21 @@ public extension MailboxManager {
591604
writableRealm.delete(orphanMessages)
592605
}
593606

607+
private func resetFolder(_ folder: Folder) async throws {
608+
try writeTransaction { realm in
609+
guard let liveFolder = folder.fresh(using: realm) else { return }
610+
611+
liveFolder.remainingOldMessagesToFetch = Constants.messageQuantityLimit
612+
liveFolder.oldMessagesUidsToFetch.removeAll()
613+
liveFolder.newMessagesUidsToFetch.removeAll()
614+
realm.delete(liveFolder.threads)
615+
realm.delete(liveFolder.messages)
616+
liveFolder.lastUpdate = nil
617+
liveFolder.cursor = nil
618+
liveFolder.unreadCount = 0
619+
}
620+
}
621+
594622
private func removeDuplicatedThreads(
595623
messageIds: MutableSet<String>,
596624
threadsToUpdate: inout Set<Thread>,

MailCore/Cache/MailboxManager/MailboxManager.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public final class MailboxManager: ObservableObject, MailboxManageable {
4242
enum ErrorDomain: Error {
4343
case missingFolder
4444
case missingDraft
45+
case tooManyDiffs
4546
}
4647

4748
public final class MailboxManagerConstants {

MailCore/Models/MessagesDelta.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,29 @@ public struct MessagesDelta<Flags: DeltaFlags>: Decodable, Sendable {
3535
}
3636
}
3737

38+
public extension MessagesDelta {
39+
func ensureValidDelta() throws {
40+
let deletedCount = deletedShortUids.count
41+
let addedCount = addedShortUids.count
42+
let updatedCount = updated.count
43+
44+
guard deletedCount < Constants.maxChangesCount,
45+
addedCount < Constants.maxChangesCount,
46+
updatedCount < Constants.maxChangesCount else {
47+
SentrySDK.capture(message: "tooManyDiffs") { scope in
48+
scope.setExtras([
49+
"cursor": cursor,
50+
"deletedCount": deletedCount,
51+
"addedCount": addedCount,
52+
"updatedCount": updatedCount
53+
])
54+
}
55+
56+
throw MailboxManager.ErrorDomain.tooManyDiffs
57+
}
58+
}
59+
}
60+
3861
public protocol DeltaFlags: Decodable, Sendable {
3962
var shortUid: String { get }
4063
}

MailCore/Utils/Constants.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ public enum Constants {
161161

162162
public static let messageQuantityLimit = 500
163163
public static let numberOfOldUidsToFetch = 10000
164+
public static let maxChangesCount = 10000
164165
public static let oldPageSize = 50
165166
public static let newPageSize = 200
166167
public static let contactSuggestionLimit = 5

0 commit comments

Comments
 (0)