Stop processing the send status records if we don't have anymore in a valid state yet.

This commit is contained in:
Maurice Parker 2020-12-16 10:26:25 -06:00
parent 25a9731996
commit d40d695d69

View File

@ -73,31 +73,37 @@ private extension CloudKitSendStatusOperation {
switch result { switch result {
case .success(let syncStatuses): case .success(let syncStatuses):
guard syncStatuses.count > 0 else { func stopProcessing() {
if self.showProgress { if self.showProgress {
self.refreshProgress?.completeTask() self.refreshProgress?.completeTask()
} }
os_log(.debug, log: self.log, "Done sending article statuses.") os_log(.debug, log: self.log, "Done sending article statuses.")
self.operationDelegate?.operationDidComplete(self) self.operationDelegate?.operationDidComplete(self)
}
guard syncStatuses.count > 0 else {
stopProcessing()
return return
} }
self.processStatuses(syncStatuses) { self.processStatuses(syncStatuses) { stop in
self.selectForProcessing() if stop {
stopProcessing()
} else {
self.selectForProcessing()
}
} }
case .failure(let databaseError): case .failure(let databaseError):
os_log(.error, log: self.log, "Send status error: %@.", databaseError.localizedDescription) os_log(.error, log: self.log, "Send status error: %@.", databaseError.localizedDescription)
self.operationDelegate?.cancelOperation(self) 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 { guard let account = account, let articlesZone = articlesZone else {
completion() completion(true)
return return
} }
@ -114,32 +120,34 @@ private extension CloudKitSendStatusOperation {
return CloudKitArticleStatusUpdate(articleID: key, statuses: value, article: articlesDict[key]) 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 articlesZone.modifyArticles(statusUpdates) { result in
switch result { switch result {
case .success: case .success:
self.database.deleteSelectedForProcessing(statusUpdates.map({ $0.articleID })) { _ in
func complete() { done(false)
// 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()
} }
if statusUpdates.isEmpty {
complete()
} else {
self.database.deleteSelectedForProcessing(statusUpdates.map({ $0.articleID })) { _ in
complete()
}
}
case .failure(let error): case .failure(let error):
self.database.resetSelectedForProcessing(syncStatuses.map({ $0.articleID })) { _ in self.database.resetSelectedForProcessing(syncStatuses.map({ $0.articleID })) { _ in
self.processAccountError(account, error) self.processAccountError(account, error)
os_log(.error, log: self.log, "Send article status modify articles error: %@.", error.localizedDescription) 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): case .failure(let databaseError):
self.database.resetSelectedForProcessing(syncStatuses.map({ $0.articleID })) { _ in self.database.resetSelectedForProcessing(syncStatuses.map({ $0.articleID })) { _ in
os_log(.error, log: self.log, "Send article status fetch articles error: %@.", databaseError.localizedDescription) os_log(.error, log: self.log, "Send article status fetch articles error: %@.", databaseError.localizedDescription)
completion() completion(true)
} }
} }