1

Is there any recommendation on using Alamofire's RequestRetrier to keep retrying a request until it succeeds?

The issue I'm running into is every time a retry happens it increases the memory of the app. I have a scenario that a user might make a request offline and it should eventually succeed when they regain connection.

Is it not good practice to continually retry a request? Should I use a Timer instead to to recreate the network call if it fails a few times? Should I use some other mechanism that waits for network activity and then sends up a queue of requests (any suggestions on what that would be would be appreciated!)?

Here is an example to see the memory explode. You just need to put your iPhone in airplane mode (so there is no connection) and the memory will keep going up rapidly since the call will happen a lot in this case.

import UIKit
import Alamofire    
class ViewController: UIViewController {
    let session = Session(configuration: .default)    
    override func viewDidLoad() {
        super.viewDidLoad()
        sendRequest()
    }
    func sendRequest() {
        session.request("https://www.google.com", method: .get, interceptor: RetryHandler())
            .responseData { (responseData) in
            switch responseData.result {
            case .success(let data):
                print(String(data: data, encoding: .utf8) ?? "nope")
            case .failure(let error):
                print(error.localizedDescription)
            }
        }
    }
}

class RetryHandler: RequestInterceptor {
    func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) {
        // keep retrying on failure
        completion(.retry)
    }
}(
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
cheaze
  • 187
  • 1
  • 14
  • you should use Reachability to get a notification when the `SCNetworkReachabilityFlags` changes. https://stackoverflow.com/a/30743763/2303865 – Leo Dabus Nov 21 '20 at 15:54
  • Why does memory explode by retrying network requests? Whatever the case is, you can create a recursive function with something called linear-backoff retry, which simply delays the call based on which attempt it is. For example, the first attempt has no delay, the second attempt may have a 1-second delay, the third attempt may have a 2-second delay, etc. Within each retry, you can cancel the session and create a new one, or just retry the existing session. You can then cancel all retries after `n` retries and defer to a network-reachability notification like Leo suggested. – trndjc Nov 21 '20 at 17:26
  • I have no idea why memory goes up bsod. Seems like a possible bug. Thanks for the ideas. That sounds like an interesting approach. – cheaze Nov 21 '20 at 20:07
  • So I got a response from one of the Alamofire maintainers and he said "Alamofire Requests accumulate all of the underlying URLRequests, URLSessionTasks, and HTTPURLResponses from every retry within a single request. It's deallocated once the Request is deallocated. You can control this growth through the proper use of retry timers and limits. That is, you should only retry using a timed falloff (as Alamofire's RetryPolicy does) and should only retry for a limited number of attempts." So sounds like I need to approach this differently. – cheaze Nov 22 '20 at 00:42

0 Answers0