From 9d4f34bb7c5c53914411ae2244e70748b186bf8e Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Tue, 21 Jul 2020 18:20:13 -0500 Subject: [PATCH] Only let one process renew the access token at a time for Reddit --- .../Reddit/RedditFeedProvider.swift | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Frameworks/Account/FeedProvider/Reddit/RedditFeedProvider.swift b/Frameworks/Account/FeedProvider/Reddit/RedditFeedProvider.swift index b293e69f8..0800e63c9 100644 --- a/Frameworks/Account/FeedProvider/Reddit/RedditFeedProvider.swift +++ b/Frameworks/Account/FeedProvider/Reddit/RedditFeedProvider.swift @@ -50,6 +50,7 @@ public final class RedditFeedProvider: FeedProvider { public var username: String? + private var refreshingAuthToken = false private var oauthToken: String private var oauthRefreshToken: String @@ -410,27 +411,37 @@ private extension RedditFeedProvider { func handleFailure(error: OAuthSwiftError, completion: @escaping (Error?) -> Void) { if case .tokenExpired = error { + if refreshingAuthToken { + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { + completion(nil) + } + } + + refreshingAuthToken = true os_log(.debug, log: self.log, "Access token expired, attempting to renew...") oauthSwift?.renewAccessToken(withRefreshToken: oauthRefreshToken) { [weak self] result in - guard let strongSelf = self, let username = strongSelf.username else { + guard let self = self, let username = self.username else { completion(nil) return } switch result { case .success(let tokenSuccess): - strongSelf.oauthToken = tokenSuccess.credential.oauthToken - strongSelf.oauthRefreshToken = tokenSuccess.credential.oauthRefreshToken + self.oauthToken = tokenSuccess.credential.oauthToken + self.oauthRefreshToken = tokenSuccess.credential.oauthRefreshToken do { - try Self.storeCredentials(username: username, oauthToken: strongSelf.oauthToken, oauthRefreshToken: strongSelf.oauthRefreshToken) - os_log(.debug, log: strongSelf.log, "Access token renewed.") + try Self.storeCredentials(username: username, oauthToken: self.oauthToken, oauthRefreshToken: self.oauthRefreshToken) + os_log(.debug, log: self.log, "Access token renewed.") } catch { + self.refreshingAuthToken = false completion(error) return } + self.refreshingAuthToken = false completion(nil) case .failure(let oathError): + self.refreshingAuthToken = false completion(oathError) } }