iOS - механизм повтора - PullRequest
       27

iOS - механизм повтора

0 голосов
/ 16 сентября 2018

Итак, я пытаюсь создать функцию повтора для сетевых вызовов (первый уровень).Это функция:

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, повторная попытка не работает так, как хотелось бы, и она не остановится никогда.

Есть предложения по новой функции или, может быть, как исправить?

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

Так что мне удалось найти проблему.Функция повтора работает нормально, но повторяется, потому что я не останавливаю таймер в refreshSession, поэтому через 3 раза он повторяется.

0 голосов
/ 16 сентября 2018

Я думаю Шаблон CircuitBreaker - это то, что вам нужно

Основная идея автоматического выключателя очень проста. Вы помещаете вызов защищенной функции в объект автоматического выключателя, который отслеживает сбои. Как только отказы достигают определенного порогового значения, автоматический выключатель отключается, и все последующие вызовы автоматического выключателя возвращаются с ошибкой, при этом вообще не выполняется защищенный вызов

см. это

...