Update sync code to handle async selectForProcessing.

This commit is contained in:
Brent Simmons 2019-12-16 12:49:07 -08:00
parent 7b7346d010
commit 3981312d6f
4 changed files with 147 additions and 106 deletions

View File

@ -195,19 +195,20 @@ final class FeedWranglerAccountDelegate: AccountDelegate {
} }
} }
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) { func sendArticleStatus(for account: Account, completion: @escaping VoidResultCompletionBlock) {
os_log(.debug, log: log, "Sending article status...") os_log(.debug, log: log, "Sending article status...")
let syncStatuses = database.selectForProcessing() database.selectForProcessing { result in
func processStatuses(_ syncStatuses: [SyncStatus]) {
let articleStatuses = Dictionary(grouping: syncStatuses, by: { $0.articleID }) let articleStatuses = Dictionary(grouping: syncStatuses, by: { $0.articleID })
let group = DispatchGroup() let group = DispatchGroup()
articleStatuses.forEach { articleID, statuses in articleStatuses.forEach { articleID, statuses in
group.enter() group.enter()
caller.updateArticleStatus(articleID, statuses) { self.caller.updateArticleStatus(articleID, statuses) {
group.leave() group.leave()
} }
} }
group.notify(queue: DispatchQueue.main) { group.notify(queue: DispatchQueue.main) {
@ -216,6 +217,15 @@ final class FeedWranglerAccountDelegate: AccountDelegate {
} }
} }
switch result {
case .success(let syncStatuses):
processStatuses(syncStatuses)
case .failure(let databaseError):
completion(.failure(databaseError))
}
}
}
func refreshArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) { func refreshArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
os_log(.debug, log: log, "Refreshing article status...") os_log(.debug, log: log, "Refreshing article status...")
let group = DispatchGroup() let group = DispatchGroup()

View File

@ -110,7 +110,9 @@ final class FeedbinAccountDelegate: AccountDelegate {
os_log(.debug, log: log, "Sending article statuses...") os_log(.debug, log: log, "Sending article statuses...")
let syncStatuses = database.selectForProcessing() database.selectForProcessing { result in
func processStatuses(_ syncStatuses: [SyncStatus]) {
let createUnreadStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.read && $0.flag == false } let createUnreadStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.read && $0.flag == false }
let deleteUnreadStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.read && $0.flag == true } let deleteUnreadStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.read && $0.flag == true }
let createStarredStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.starred && $0.flag == true } let createStarredStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.starred && $0.flag == true }
@ -120,7 +122,7 @@ final class FeedbinAccountDelegate: AccountDelegate {
var errorOccurred = false var errorOccurred = false
group.enter() group.enter()
sendArticleStatuses(createUnreadStatuses, apiCall: caller.createUnreadEntries) { result in self.sendArticleStatuses(createUnreadStatuses, apiCall: self.caller.createUnreadEntries) { result in
group.leave() group.leave()
if case .failure = result { if case .failure = result {
errorOccurred = true errorOccurred = true
@ -128,7 +130,7 @@ final class FeedbinAccountDelegate: AccountDelegate {
} }
group.enter() group.enter()
sendArticleStatuses(deleteUnreadStatuses, apiCall: caller.deleteUnreadEntries) { result in self.sendArticleStatuses(deleteUnreadStatuses, apiCall: self.caller.deleteUnreadEntries) { result in
group.leave() group.leave()
if case .failure = result { if case .failure = result {
errorOccurred = true errorOccurred = true
@ -136,7 +138,7 @@ final class FeedbinAccountDelegate: AccountDelegate {
} }
group.enter() group.enter()
sendArticleStatuses(createStarredStatuses, apiCall: caller.createStarredEntries) { result in self.sendArticleStatuses(createStarredStatuses, apiCall: self.caller.createStarredEntries) { result in
group.leave() group.leave()
if case .failure = result { if case .failure = result {
errorOccurred = true errorOccurred = true
@ -144,7 +146,7 @@ final class FeedbinAccountDelegate: AccountDelegate {
} }
group.enter() group.enter()
sendArticleStatuses(deleteStarredStatuses, apiCall: caller.deleteStarredEntries) { result in self.sendArticleStatuses(deleteStarredStatuses, apiCall: self.caller.deleteStarredEntries) { result in
group.leave() group.leave()
if case .failure = result { if case .failure = result {
errorOccurred = true errorOccurred = true
@ -159,7 +161,15 @@ final class FeedbinAccountDelegate: AccountDelegate {
completion(.success(())) completion(.success(()))
} }
} }
}
switch result {
case .success(let syncStatuses):
processStatuses(syncStatuses)
case .failure(let databaseError):
completion(.failure(databaseError))
}
}
} }
func refreshArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) { func refreshArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {

View File

@ -31,8 +31,20 @@ final class FeedlySendArticleStatusesOperation: FeedlyOperation {
os_log(.debug, log: log, "Sending article statuses...") os_log(.debug, log: log, "Sending article statuses...")
let pending = database.selectForProcessing() database.selectForProcessing { result in
switch result {
case .success(let syncStatuses):
self.processStatuses(syncStatuses)
case .failure:
self.didFinish()
}
}
}
}
private extension FeedlySendArticleStatusesOperation {
func processStatuses(_ pending: [SyncStatus]) {
let statuses: [(status: ArticleStatus.Key, flag: Bool, action: FeedlyMarkAction)] = [ let statuses: [(status: ArticleStatus.Key, flag: Bool, action: FeedlyMarkAction)] = [
(.read, false, .unread), (.read, false, .unread),
(.read, true, .read), (.read, true, .read),
@ -55,11 +67,11 @@ final class FeedlySendArticleStatusesOperation: FeedlyOperation {
assert(Thread.isMainThread) assert(Thread.isMainThread)
switch result { switch result {
case .success: case .success:
database.deleteSelectedForProcessing(Array(ids)) { database.deleteSelectedForProcessing(Array(ids)) { _ in
group.leave() group.leave()
} }
case .failure: case .failure:
database.resetSelectedForProcessing(Array(ids)) { database.resetSelectedForProcessing(Array(ids)) { _ in
group.leave() group.leave()
} }
} }

View File

@ -113,10 +113,11 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
} }
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) { func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
os_log(.debug, log: log, "Sending article statuses...") os_log(.debug, log: log, "Sending article statuses...")
let syncStatuses = database.selectForProcessing() database.selectForProcessing { result in
func processStatuses(_ syncStatuses: [SyncStatus]) {
let createUnreadStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.read && $0.flag == false } let createUnreadStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.read && $0.flag == false }
let deleteUnreadStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.read && $0.flag == true } let deleteUnreadStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.read && $0.flag == true }
let createStarredStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.starred && $0.flag == true } let createStarredStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.starred && $0.flag == true }
@ -125,22 +126,22 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
let group = DispatchGroup() let group = DispatchGroup()
group.enter() group.enter()
sendArticleStatuses(createUnreadStatuses, apiCall: caller.createUnreadEntries) { self.sendArticleStatuses(createUnreadStatuses, apiCall: self.caller.createUnreadEntries) {
group.leave() group.leave()
} }
group.enter() group.enter()
sendArticleStatuses(deleteUnreadStatuses, apiCall: caller.deleteUnreadEntries) { self.sendArticleStatuses(deleteUnreadStatuses, apiCall: self.caller.deleteUnreadEntries) {
group.leave() group.leave()
} }
group.enter() group.enter()
sendArticleStatuses(createStarredStatuses, apiCall: caller.createStarredEntries) { self.sendArticleStatuses(createStarredStatuses, apiCall: self.caller.createStarredEntries) {
group.leave() group.leave()
} }
group.enter() group.enter()
sendArticleStatuses(deleteStarredStatuses, apiCall: caller.deleteStarredEntries) { self.sendArticleStatuses(deleteStarredStatuses, apiCall: self.caller.deleteStarredEntries) {
group.leave() group.leave()
} }
@ -148,7 +149,15 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
os_log(.debug, log: self.log, "Done sending article statuses.") os_log(.debug, log: self.log, "Done sending article statuses.")
completion(.success(())) completion(.success(()))
} }
}
switch result {
case .success(let syncStatuses):
processStatuses(syncStatuses)
case .failure(let databaseError):
completion(.failure(databaseError))
}
}
} }
func refreshArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) { func refreshArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {