Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Refresh auth token
enum DelayType {
case immediate()
case constant(time: Double)
case exponential(initial: Double, multiplier: Double, maxDelay: Double)
case custom(closure: (Int) -> Double)
}
extension DelayType {
func make(_ attempt: Int) -> Double {
switch self {
case .immediate: return 0.0
case let .constant(time): return time
case let .exponential(initial, multiplier, maxDelay):
let delay = attempt == 1 ? initial : initial * pow(multiplier, Double(attempt - 1))
return min(maxDelay, delay)
case let .custom(closure): return closure(attempt)
}
}
}
extension ObservableType where E: Response {
func retryWithAuthIfNeeded(token _: CoinsBankTargetType, initialSequence: Observable<Void>) -> Observable<E> {
let countdown = Observable.range(start: 1, count: 3)
return retryWhen { (e: Observable<Swift.Error>) in
Observable.zip(e, countdown)
.flatMap({ error, attempt -> Observable<Void> in
let error = error as NSError
guard [-33102].contains(error.code) else {
throw error
}
/// Чистим текущие данные токена
let single = Managers.sh.singletonContainer
let storage: Secure = try single.resolve()
storage.clearServerToken()
if attempt == 3 {
/// Все это фиаско, блокируем приложение
let signalCenter: SignalCenter = try single.resolve()
signalCenter.postSignal(.immediatelyLockApp)
throw NSError.create("Something wrong with user authorization, try login again")
} else {
let delay = DelayType.exponential(initial: 1, multiplier: 1.5, maxDelay: 4)
let interval = delay.make(attempt)
return Observable<Int64>
.timer(
RxTimeInterval(interval),
scheduler: ALSchedulers.sh.main
).flatMap { _ in initialSequence }
}
})
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.