Update sync code to handle async selectForProcessing.
This commit is contained in:
parent
7b7346d010
commit
3981312d6f
|
@ -195,24 +195,34 @@ 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...")
|
||||
|
||||
let syncStatuses = database.selectForProcessing()
|
||||
let articleStatuses = Dictionary(grouping: syncStatuses, by: { $0.articleID })
|
||||
let group = DispatchGroup()
|
||||
|
||||
articleStatuses.forEach { articleID, statuses in
|
||||
group.enter()
|
||||
caller.updateArticleStatus(articleID, statuses) {
|
||||
group.leave()
|
||||
|
||||
database.selectForProcessing { result in
|
||||
|
||||
func processStatuses(_ syncStatuses: [SyncStatus]) {
|
||||
let articleStatuses = Dictionary(grouping: syncStatuses, by: { $0.articleID })
|
||||
let group = DispatchGroup()
|
||||
|
||||
articleStatuses.forEach { articleID, statuses in
|
||||
group.enter()
|
||||
self.caller.updateArticleStatus(articleID, statuses) {
|
||||
group.leave()
|
||||
}
|
||||
}
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
os_log(.debug, log: self.log, "Done sending article statuses.")
|
||||
completion(.success(()))
|
||||
}
|
||||
}
|
||||
|
||||
switch result {
|
||||
case .success(let syncStatuses):
|
||||
processStatuses(syncStatuses)
|
||||
case .failure(let databaseError):
|
||||
completion(.failure(databaseError))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
os_log(.debug, log: self.log, "Done sending article statuses.")
|
||||
completion(.success(()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -109,57 +109,67 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
|||
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
|
||||
|
||||
os_log(.debug, log: log, "Sending article statuses...")
|
||||
|
||||
let syncStatuses = database.selectForProcessing()
|
||||
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 createStarredStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.starred && $0.flag == true }
|
||||
let deleteStarredStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.starred && $0.flag == false }
|
||||
|
||||
let group = DispatchGroup()
|
||||
var errorOccurred = false
|
||||
database.selectForProcessing { result in
|
||||
|
||||
group.enter()
|
||||
sendArticleStatuses(createUnreadStatuses, apiCall: caller.createUnreadEntries) { result in
|
||||
group.leave()
|
||||
if case .failure = result {
|
||||
errorOccurred = true
|
||||
func processStatuses(_ syncStatuses: [SyncStatus]) {
|
||||
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 createStarredStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.starred && $0.flag == true }
|
||||
let deleteStarredStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.starred && $0.flag == false }
|
||||
|
||||
let group = DispatchGroup()
|
||||
var errorOccurred = false
|
||||
|
||||
group.enter()
|
||||
self.sendArticleStatuses(createUnreadStatuses, apiCall: self.caller.createUnreadEntries) { result in
|
||||
group.leave()
|
||||
if case .failure = result {
|
||||
errorOccurred = true
|
||||
}
|
||||
}
|
||||
|
||||
group.enter()
|
||||
self.sendArticleStatuses(deleteUnreadStatuses, apiCall: self.caller.deleteUnreadEntries) { result in
|
||||
group.leave()
|
||||
if case .failure = result {
|
||||
errorOccurred = true
|
||||
}
|
||||
}
|
||||
|
||||
group.enter()
|
||||
self.sendArticleStatuses(createStarredStatuses, apiCall: self.caller.createStarredEntries) { result in
|
||||
group.leave()
|
||||
if case .failure = result {
|
||||
errorOccurred = true
|
||||
}
|
||||
}
|
||||
|
||||
group.enter()
|
||||
self.sendArticleStatuses(deleteStarredStatuses, apiCall: self.caller.deleteStarredEntries) { result in
|
||||
group.leave()
|
||||
if case .failure = result {
|
||||
errorOccurred = true
|
||||
}
|
||||
}
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
os_log(.debug, log: self.log, "Done sending article statuses.")
|
||||
if errorOccurred {
|
||||
completion(.failure(FeedbinAccountDelegateError.unknown))
|
||||
} else {
|
||||
completion(.success(()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch result {
|
||||
case .success(let syncStatuses):
|
||||
processStatuses(syncStatuses)
|
||||
case .failure(let databaseError):
|
||||
completion(.failure(databaseError))
|
||||
}
|
||||
}
|
||||
|
||||
group.enter()
|
||||
sendArticleStatuses(deleteUnreadStatuses, apiCall: caller.deleteUnreadEntries) { result in
|
||||
group.leave()
|
||||
if case .failure = result {
|
||||
errorOccurred = true
|
||||
}
|
||||
}
|
||||
|
||||
group.enter()
|
||||
sendArticleStatuses(createStarredStatuses, apiCall: caller.createStarredEntries) { result in
|
||||
group.leave()
|
||||
if case .failure = result {
|
||||
errorOccurred = true
|
||||
}
|
||||
}
|
||||
|
||||
group.enter()
|
||||
sendArticleStatuses(deleteStarredStatuses, apiCall: caller.deleteStarredEntries) { result in
|
||||
group.leave()
|
||||
if case .failure = result {
|
||||
errorOccurred = true
|
||||
}
|
||||
}
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
os_log(.debug, log: self.log, "Done sending article statuses.")
|
||||
if errorOccurred {
|
||||
completion(.failure(FeedbinAccountDelegateError.unknown))
|
||||
} else {
|
||||
completion(.success(()))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func refreshArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
|
||||
|
@ -531,7 +541,7 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
return account.update(articles, statusKey: statusKey, flag: flag)
|
||||
return account.update(articles, statusKey: statusKey, flag: flag)
|
||||
}
|
||||
|
||||
func accountDidInitialize(_ account: Account) {
|
||||
|
|
|
@ -30,24 +30,36 @@ final class FeedlySendArticleStatusesOperation: FeedlyOperation {
|
|||
}
|
||||
|
||||
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)] = [
|
||||
(.read, false, .unread),
|
||||
(.read, true, .read),
|
||||
(.starred, true, .saved),
|
||||
(.starred, false, .unsaved),
|
||||
]
|
||||
|
||||
|
||||
let group = DispatchGroup()
|
||||
|
||||
|
||||
for pairing in statuses {
|
||||
let articleIds = pending.filter { $0.key == pairing.status && $0.flag == pairing.flag }
|
||||
guard !articleIds.isEmpty else {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
let ids = Set(articleIds.map { $0.articleID })
|
||||
let database = self.database
|
||||
group.enter()
|
||||
|
@ -55,17 +67,17 @@ final class FeedlySendArticleStatusesOperation: FeedlyOperation {
|
|||
assert(Thread.isMainThread)
|
||||
switch result {
|
||||
case .success:
|
||||
database.deleteSelectedForProcessing(Array(ids)) {
|
||||
database.deleteSelectedForProcessing(Array(ids)) { _ in
|
||||
group.leave()
|
||||
}
|
||||
case .failure:
|
||||
database.resetSelectedForProcessing(Array(ids)) {
|
||||
database.resetSelectedForProcessing(Array(ids)) { _ in
|
||||
group.leave()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
os_log(.debug, log: self.log, "Done sending article statuses.")
|
||||
self.didFinish()
|
||||
|
|
|
@ -113,42 +113,51 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
|
|||
}
|
||||
|
||||
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
|
||||
|
||||
os_log(.debug, log: log, "Sending article statuses...")
|
||||
|
||||
let syncStatuses = database.selectForProcessing()
|
||||
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 createStarredStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.starred && $0.flag == true }
|
||||
let deleteStarredStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.starred && $0.flag == false }
|
||||
|
||||
let group = DispatchGroup()
|
||||
|
||||
group.enter()
|
||||
sendArticleStatuses(createUnreadStatuses, apiCall: caller.createUnreadEntries) {
|
||||
group.leave()
|
||||
database.selectForProcessing { result in
|
||||
|
||||
func processStatuses(_ syncStatuses: [SyncStatus]) {
|
||||
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 createStarredStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.starred && $0.flag == true }
|
||||
let deleteStarredStatuses = syncStatuses.filter { $0.key == ArticleStatus.Key.starred && $0.flag == false }
|
||||
|
||||
let group = DispatchGroup()
|
||||
|
||||
group.enter()
|
||||
self.sendArticleStatuses(createUnreadStatuses, apiCall: self.caller.createUnreadEntries) {
|
||||
group.leave()
|
||||
}
|
||||
|
||||
group.enter()
|
||||
self.sendArticleStatuses(deleteUnreadStatuses, apiCall: self.caller.deleteUnreadEntries) {
|
||||
group.leave()
|
||||
}
|
||||
|
||||
group.enter()
|
||||
self.sendArticleStatuses(createStarredStatuses, apiCall: self.caller.createStarredEntries) {
|
||||
group.leave()
|
||||
}
|
||||
|
||||
group.enter()
|
||||
self.sendArticleStatuses(deleteStarredStatuses, apiCall: self.caller.deleteStarredEntries) {
|
||||
group.leave()
|
||||
}
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
os_log(.debug, log: self.log, "Done sending article statuses.")
|
||||
completion(.success(()))
|
||||
}
|
||||
}
|
||||
|
||||
switch result {
|
||||
case .success(let syncStatuses):
|
||||
processStatuses(syncStatuses)
|
||||
case .failure(let databaseError):
|
||||
completion(.failure(databaseError))
|
||||
}
|
||||
}
|
||||
|
||||
group.enter()
|
||||
sendArticleStatuses(deleteUnreadStatuses, apiCall: caller.deleteUnreadEntries) {
|
||||
group.leave()
|
||||
}
|
||||
|
||||
group.enter()
|
||||
sendArticleStatuses(createStarredStatuses, apiCall: caller.createStarredEntries) {
|
||||
group.leave()
|
||||
}
|
||||
|
||||
group.enter()
|
||||
sendArticleStatuses(deleteStarredStatuses, apiCall: caller.deleteStarredEntries) {
|
||||
group.leave()
|
||||
}
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
os_log(.debug, log: self.log, "Done sending article statuses.")
|
||||
completion(.success(()))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func refreshArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
|
||||
|
|
Loading…
Reference in New Issue