[英]RequestRetrier Alamofire lock not working
我正在用Alamofire實現RequestRetrier,以刷新給定用戶的accessToken。
func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) {
lock.lock() ; defer { lock.unlock() }
if let response = request.task?.response as? HTTPURLResponse, response.statusCode == 401 {
requestsToRetry.append(completion)
if !isRefreshing {
refreshToken(completion: { [weak self] succeded, accessToken in
guard let strongSelf = self else { return }
strongSelf.lock.lock() ; defer { strongSelf.lock.unlock() }
strongSelf.requestsToRetry.forEach{ $0(succeded, 0.0) }
strongSelf.requestsToRetry.removeAll()
})
}
} else {
completion(false, 0.0)
}
}
當strongSelf.lock.lock() ; defer { strongSelf.lock.unlock() }
strongSelf.lock.lock() ; defer { strongSelf.lock.unlock() }
被稱為它不會繼續執行,因此存在無限循環。 我嘗試檢查strongSelf.lock.try()
的結果並返回false。
當我使用錯誤的密碼登錄時會發生這種情況,因此服務器返回401。
這是我的refreshToken代碼
guard !isRefreshing else { return }
// ... Get user ... //
if let user = user {
isRefreshing = true
signIn(user: userDTO)
.subscribe(onNext: { [weak self] userSession in
guard let strongSelf = self else { return }
// ... Save accessToken ... //
completion(true, userSession.accessToken)
strongSelf.isRefreshing = false
}, onError: { [weak self] error in
guard let strongSelf = self else { return }
// ... Log out user ... //
completion(false, nil)
strongSelf.isRefreshing = false
})
.disposed(by: bag)
} else {
completion(false, nil)
}
如Github問題https://github.com/Alamofire/Alamofire/issues/2544所示,我可以通過以下方法解決此問題:
private let lock = NSLock()
至
private let lock = NSRecursiveLock()
它們之間的區別在於,如果同一線程嘗試鎖定,則可以解鎖遞歸鎖定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.