iOS - 重试机制
iOS - retry mechanism
所以我正在尝试为我的网络调用(第一层)构建一个重试函数。
这是函数:
func retry<T>(_ attempts: Int, task: @escaping (_ success: @escaping (T) -> Void, _ failure: @escaping (String) -> Void) -> Void, success: @escaping (T) -> Void, failure: @escaping (String) -> Void) {
task({ (obj) in
success(obj)
}) { (error) in
print("Error retry left \(attempts)")
if attempts > 1 {
self.retry(attempts - 1, task: task, success: success, failure: failure)
} else {
failure(error)
}
}
}
实现是这样的:
func refreshSession(success: @escaping () -> Void, failure: @escaping (String) -> Void) {
cameraProtocols?.refreshSession( success: {
print("calling serverping")
self.timer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true, block: { (timer) in
self.keepAlive(session: CameraManager.session, success: {
print("serverping succsess")
success()
}, failure: { (error) in
print(error)
failure(error)
})
})
}, failure: { (error) in
print(error)
failure(error)
})
}
func keepAlive(session: String, success: @escaping () -> Void, failure: @escaping (String) -> Void) {
cameraProtocols?.keepAlive(session: CameraManager.session, success: {
print("server ping done!")
NotificationCenter.default.post(name: Notification.Name(rawValue: "pingSuccess"), object: nil)
success()
}, failure: { (error) in
print(error)
self.retry(3, task: { (success, failure) in
self.refreshSession(success: success, failure: failure)
}, success: { (success) in
print("refresh succsed from retry")
success
}, failure: { (e) in
print("refresh failed from retry: \(e)")
//TODO - handle error logic when to procced with the failure closure
failure(error)
})
NotificationCenter.default.post(name: Notification.Name(rawValue: "faildPing"), object: nil)
})
}
当我故意使 keepalive 调用失败时,重试不会按预期工作并且永远不会停止。
对新功能有什么建议或者如何修复吗?
我认为 CircuitBreaker Pattern 是您所需要的
断路器背后的基本思想非常简单。您将受保护的函数调用包装在断路器对象中,该对象会监视故障。一旦故障达到某个阈值,断路器就会跳闸,所有对断路器的进一步调用都会出错 return,根本不会进行受保护的调用
见this
所以我设法找到了问题所在。
重试函数工作正常,但它会重复,因为我没有在 refreshSession 中停止计时器,所以在重复 3 次后它会重复。
所以我正在尝试为我的网络调用(第一层)构建一个重试函数。 这是函数:
func retry<T>(_ attempts: Int, task: @escaping (_ success: @escaping (T) -> Void, _ failure: @escaping (String) -> Void) -> Void, success: @escaping (T) -> Void, failure: @escaping (String) -> Void) {
task({ (obj) in
success(obj)
}) { (error) in
print("Error retry left \(attempts)")
if attempts > 1 {
self.retry(attempts - 1, task: task, success: success, failure: failure)
} else {
failure(error)
}
}
}
实现是这样的:
func refreshSession(success: @escaping () -> Void, failure: @escaping (String) -> Void) {
cameraProtocols?.refreshSession( success: {
print("calling serverping")
self.timer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true, block: { (timer) in
self.keepAlive(session: CameraManager.session, success: {
print("serverping succsess")
success()
}, failure: { (error) in
print(error)
failure(error)
})
})
}, failure: { (error) in
print(error)
failure(error)
})
}
func keepAlive(session: String, success: @escaping () -> Void, failure: @escaping (String) -> Void) {
cameraProtocols?.keepAlive(session: CameraManager.session, success: {
print("server ping done!")
NotificationCenter.default.post(name: Notification.Name(rawValue: "pingSuccess"), object: nil)
success()
}, failure: { (error) in
print(error)
self.retry(3, task: { (success, failure) in
self.refreshSession(success: success, failure: failure)
}, success: { (success) in
print("refresh succsed from retry")
success
}, failure: { (e) in
print("refresh failed from retry: \(e)")
//TODO - handle error logic when to procced with the failure closure
failure(error)
})
NotificationCenter.default.post(name: Notification.Name(rawValue: "faildPing"), object: nil)
})
}
当我故意使 keepalive 调用失败时,重试不会按预期工作并且永远不会停止。
对新功能有什么建议或者如何修复吗?
我认为 CircuitBreaker Pattern 是您所需要的
断路器背后的基本思想非常简单。您将受保护的函数调用包装在断路器对象中,该对象会监视故障。一旦故障达到某个阈值,断路器就会跳闸,所有对断路器的进一步调用都会出错 return,根本不会进行受保护的调用
见this
所以我设法找到了问题所在。 重试函数工作正常,但它会重复,因为我没有在 refreshSession 中停止计时器,所以在重复 3 次后它会重复。