From d40d695d6941906524fd1fb52bfffc63529c614d Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Wed, 16 Dec 2020 10:26:25 -0600 Subject: [PATCH] Stop processing the send status records if we don't have anymore in a valid state yet. --- .../CloudKitSendStatusOperation.swift | 60 +++++++++++-------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift b/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift index e41ef3ea0..30c983ef2 100644 --- a/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift +++ b/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift @@ -73,31 +73,37 @@ private extension CloudKitSendStatusOperation { switch result { case .success(let syncStatuses): - guard syncStatuses.count > 0 else { + func stopProcessing() { if self.showProgress { self.refreshProgress?.completeTask() } os_log(.debug, log: self.log, "Done sending article statuses.") self.operationDelegate?.operationDidComplete(self) + } + + guard syncStatuses.count > 0 else { + stopProcessing() return } - self.processStatuses(syncStatuses) { - self.selectForProcessing() + self.processStatuses(syncStatuses) { stop in + if stop { + stopProcessing() + } else { + self.selectForProcessing() + } } case .failure(let databaseError): - os_log(.error, log: self.log, "Send status error: %@.", databaseError.localizedDescription) self.operationDelegate?.cancelOperation(self) - } } } - func processStatuses(_ syncStatuses: [SyncStatus], completion: @escaping () -> Void) { + func processStatuses(_ syncStatuses: [SyncStatus], completion: @escaping (Bool) -> Void) { guard let account = account, let articlesZone = articlesZone else { - completion() + completion(true) return } @@ -114,32 +120,34 @@ private extension CloudKitSendStatusOperation { return CloudKitArticleStatusUpdate(articleID: key, statuses: value, article: articlesDict[key]) } + func done(_ stop: Bool) { + // Don't clear the last one since we might have had additional ticks added + if self.showProgress && self.refreshProgress?.numberRemaining ?? 0 > 1 { + self.refreshProgress?.completeTask() + } + os_log(.debug, log: self.log, "Done sending article status block...") + completion(stop) + } + + // If this happens, we have somehow gotten into a state where we have new status records + // but the articles didn't come back in the fetch. Rather than crashing, we stop processing + // and hope that it gets cleared up later. + guard !statusUpdates.isEmpty else { + done(true) + return + } + articlesZone.modifyArticles(statusUpdates) { result in switch result { case .success: - - func complete() { - // Don't clear the last one since we might have had additional ticks added - if self.showProgress && self.refreshProgress?.numberRemaining ?? 0 > 1 { - self.refreshProgress?.completeTask() - } - os_log(.debug, log: self.log, "Done sending article status block...") - completion() + self.database.deleteSelectedForProcessing(statusUpdates.map({ $0.articleID })) { _ in + done(false) } - - if statusUpdates.isEmpty { - complete() - } else { - self.database.deleteSelectedForProcessing(statusUpdates.map({ $0.articleID })) { _ in - complete() - } - } - case .failure(let error): self.database.resetSelectedForProcessing(syncStatuses.map({ $0.articleID })) { _ in self.processAccountError(account, error) os_log(.error, log: self.log, "Send article status modify articles error: %@.", error.localizedDescription) - completion() + completion(true) } } } @@ -152,7 +160,7 @@ private extension CloudKitSendStatusOperation { case .failure(let databaseError): self.database.resetSelectedForProcessing(syncStatuses.map({ $0.articleID })) { _ in os_log(.error, log: self.log, "Send article status fetch articles error: %@.", databaseError.localizedDescription) - completion() + completion(true) } }