Made sync status sequential so that we stop losing statuses when we automatically send them on exceeding 100 statuses

This commit is contained in:
Maurice Parker 2020-04-29 16:14:18 -05:00
parent d30987ca0a
commit 0b49acfabc
8 changed files with 41 additions and 63 deletions

View File

@ -465,7 +465,9 @@ final class CloudKitAccountDelegate: AccountDelegate {
let syncStatuses = articles.map { article in let syncStatuses = articles.map { article in
return SyncStatus(articleID: article.articleID, key: SyncStatus.Key(statusKey), flag: flag) return SyncStatus(articleID: article.articleID, key: SyncStatus.Key(statusKey), flag: flag)
} }
database.insertStatuses(syncStatuses)
try? database.insertStatuses(syncStatuses)
let articles = try? account.update(articles, statusKey: statusKey, flag: flag)
database.selectPendingCount { result in database.selectPendingCount { result in
if let count = try? result.get(), count > 100 { if let count = try? result.get(), count > 100 {
@ -473,7 +475,7 @@ final class CloudKitAccountDelegate: AccountDelegate {
} }
} }
return try? account.update(articles, statusKey: statusKey, flag: flag) return articles
} }
func accountDidInitialize(_ account: Account) { func accountDidInitialize(_ account: Account) {
@ -636,10 +638,9 @@ private extension CloudKitAccountDelegate {
account.update(webFeed.webFeedID, with: parsedItems) { result in account.update(webFeed.webFeedID, with: parsedItems) { result in
switch result { switch result {
case .success(let articleChanges): case .success(let articleChanges):
self.storeArticleChanges(new: articleChanges.newArticles, updated: articleChanges.updatedArticles, deleted: articleChanges.deletedArticles) { self.storeArticleChanges(new: articleChanges.newArticles, updated: articleChanges.updatedArticles, deleted: articleChanges.deletedArticles)
self.refreshProgress.completeTask() self.refreshProgress.completeTask()
group.leave() group.leave()
}
case .failure(let error): case .failure(let error):
os_log(.error, log: self.log, "CloudKit Feed refresh update error: %@.", error.localizedDescription) os_log(.error, log: self.log, "CloudKit Feed refresh update error: %@.", error.localizedDescription)
self.refreshProgress.completeTask() self.refreshProgress.completeTask()
@ -661,10 +662,9 @@ private extension CloudKitAccountDelegate {
group.enter() group.enter()
refresher.refreshFeeds(refresherWebFeeds) { refresherNewArticles, refresherUpdatedArticles, refresherDeletedArticles in refresher.refreshFeeds(refresherWebFeeds) { refresherNewArticles, refresherUpdatedArticles, refresherDeletedArticles in
self.storeArticleChanges(new: refresherNewArticles, updated: refresherUpdatedArticles, deleted: refresherDeletedArticles) { self.storeArticleChanges(new: refresherNewArticles, updated: refresherUpdatedArticles, deleted: refresherDeletedArticles)
group.leave() group.leave()
} }
}
group.notify(queue: DispatchQueue.main) { group.notify(queue: DispatchQueue.main) {
self.sendArticleStatus(for: account) { _ in self.sendArticleStatus(for: account) { _ in
@ -811,7 +811,7 @@ private extension CloudKitAccountDelegate {
account.fetchArticlesAsync(.webFeed(feed)) { result in account.fetchArticlesAsync(.webFeed(feed)) { result in
switch result { switch result {
case .success(let articles): case .success(let articles):
self.storeArticleChanges(new: articles, updated: Set<Article>(), deleted: Set<Article>()) { self.storeArticleChanges(new: articles, updated: Set<Article>(), deleted: Set<Article>())
self.sendArticleStatus(for: account) { result in self.sendArticleStatus(for: account) { result in
switch result { switch result {
case .success: case .success:
@ -824,7 +824,6 @@ private extension CloudKitAccountDelegate {
completion(.failure(error)) completion(.failure(error))
} }
} }
}
case .failure(let error): case .failure(let error):
self.refreshProgress.clear() self.refreshProgress.clear()
completion(.failure(error)) completion(.failure(error))
@ -841,40 +840,20 @@ private extension CloudKitAccountDelegate {
} }
} }
func storeArticleChanges(new: Set<Article>?, updated: Set<Article>?, deleted: Set<Article>?, completion: @escaping () -> Void) { func storeArticleChanges(new: Set<Article>?, updated: Set<Article>?, deleted: Set<Article>?) {
let group = DispatchGroup() insertSyncStatuses(articles: new, statusKey: .new, flag: true)
insertSyncStatuses(articles: updated, statusKey: .new, flag: false)
group.enter() insertSyncStatuses(articles: deleted, statusKey: .deleted, flag: true)
insertSyncStatuses(articles: new, statusKey: .new, flag: true) {
group.leave()
} }
group.enter() func insertSyncStatuses(articles: Set<Article>?, statusKey: SyncStatus.Key, flag: Bool) {
insertSyncStatuses(articles: updated, statusKey: .new, flag: false) {
group.leave()
}
group.enter()
insertSyncStatuses(articles: deleted, statusKey: .deleted, flag: true) {
group.leave()
}
group.notify(queue: DispatchQueue.main) {
completion()
}
}
func insertSyncStatuses(articles: Set<Article>?, statusKey: SyncStatus.Key, flag: Bool, completion: @escaping () -> Void) {
guard let articles = articles else { guard let articles = articles else {
completion()
return return
} }
let syncStatuses = articles.map { article in let syncStatuses = articles.map { article in
return SyncStatus(articleID: article.articleID, key: statusKey, flag: flag) return SyncStatus(articleID: article.articleID, key: statusKey, flag: flag)
} }
database.insertStatuses(syncStatuses) { _ in try? database.insertStatuses(syncStatuses)
completion()
}
} }
} }

View File

@ -437,7 +437,7 @@ final class FeedWranglerAccountDelegate: AccountDelegate {
func markArticles(for account: Account, articles: Set<Article>, statusKey: ArticleStatus.Key, flag: Bool) -> Set<Article>? { func markArticles(for account: Account, articles: Set<Article>, statusKey: ArticleStatus.Key, flag: Bool) -> Set<Article>? {
let syncStatuses = articles.map { SyncStatus(articleID: $0.articleID, key: SyncStatus.Key(statusKey), flag: flag)} let syncStatuses = articles.map { SyncStatus(articleID: $0.articleID, key: SyncStatus.Key(statusKey), flag: flag)}
database.insertStatuses(syncStatuses) try? database.insertStatuses(syncStatuses)
database.selectPendingCount { result in database.selectPendingCount { result in
if let count = try? result.get(), count > 0 { if let count = try? result.get(), count > 0 {

View File

@ -539,7 +539,7 @@ final class FeedbinAccountDelegate: AccountDelegate {
let syncStatuses = articles.map { article in let syncStatuses = articles.map { article in
return SyncStatus(articleID: article.articleID, key: SyncStatus.Key(statusKey), flag: flag) return SyncStatus(articleID: article.articleID, key: SyncStatus.Key(statusKey), flag: flag)
} }
database.insertStatuses(syncStatuses) try? database.insertStatuses(syncStatuses)
database.selectPendingCount { result in database.selectPendingCount { result in
if let count = try? result.get(), count > 100 { if let count = try? result.get(), count > 100 {

View File

@ -492,7 +492,7 @@ final class FeedlyAccountDelegate: AccountDelegate {
return SyncStatus(articleID: article.articleID, key: SyncStatus.Key(statusKey), flag: flag) return SyncStatus(articleID: article.articleID, key: SyncStatus.Key(statusKey), flag: flag)
} }
database.insertStatuses(syncStatuses) try? database.insertStatuses(syncStatuses)
os_log(.debug, log: log, "Marking %@ as %@.", articles.map { $0.title }, syncStatuses) os_log(.debug, log: log, "Marking %@ as %@.", articles.map { $0.title }, syncStatuses)
database.selectPendingCount { result in database.selectPendingCount { result in

View File

@ -577,7 +577,7 @@ final class NewsBlurAccountDelegate: AccountDelegate {
let syncStatuses = articles.map { article in let syncStatuses = articles.map { article in
return SyncStatus(articleID: article.articleID, key: SyncStatus.Key(statusKey), flag: flag) return SyncStatus(articleID: article.articleID, key: SyncStatus.Key(statusKey), flag: flag)
} }
database.insertStatuses(syncStatuses) try? database.insertStatuses(syncStatuses)
database.selectPendingCount { result in database.selectPendingCount { result in
if let count = try? result.get(), count > 100 { if let count = try? result.get(), count > 100 {

View File

@ -414,7 +414,7 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
let syncStatuses = articles.map { article in let syncStatuses = articles.map { article in
return SyncStatus(articleID: article.articleID, key: SyncStatus.Key(statusKey), flag: flag) return SyncStatus(articleID: article.articleID, key: SyncStatus.Key(statusKey), flag: flag)
} }
database.insertStatuses(syncStatuses) try? database.insertStatuses(syncStatuses)
database.selectPendingCount { result in database.selectPendingCount { result in
if let count = try? result.get(), count > 100 { if let count = try? result.get(), count > 100 {

View File

@ -32,8 +32,8 @@ public struct SyncDatabase {
// MARK: - API // MARK: - API
public func insertStatuses(_ statuses: [SyncStatus], completion: DatabaseCompletionBlock? = nil) { public func insertStatuses(_ statuses: [SyncStatus]) throws {
syncStatusTable.insertStatuses(statuses, completion: completion) try syncStatusTable.insertStatuses(statuses)
} }
public func selectForProcessing(completion: @escaping SyncStatusesCompletionBlock) { public func selectForProcessing(completion: @escaping SyncStatusesCompletionBlock) {

View File

@ -149,22 +149,21 @@ struct SyncStatusTable: DatabaseTable {
} }
} }
func insertStatuses(_ statuses: [SyncStatus], completion: DatabaseCompletionBlock? = nil) { func insertStatuses(_ statuses: [SyncStatus]) throws {
queue.runInTransaction { databaseResult in var error: DatabaseError?
queue.runInTransactionSync { databaseResult in
func makeDatabaseCall(_ database: FMDatabase) {
let statusArray = statuses.map { $0.databaseDictionary() }
self.insertRows(statusArray, insertType: .orReplace, in: database)
}
switch databaseResult { switch databaseResult {
case .success(let database): case .success(let database):
makeDatabaseCall(database) let statusArray = statuses.map { $0.databaseDictionary() }
callCompletion(completion, nil) self.insertRows(statusArray, insertType: .orReplace, in: database)
case .failure(let databaseError): case .failure(let databaseError):
callCompletion(completion, databaseError) error = databaseError
} }
} }
if let error = error {
throw error
}
} }
} }