Home > database >  Alamofire RequestRetrier, is it ok to call the completion block on the main operation queue?
Alamofire RequestRetrier, is it ok to call the completion block on the main operation queue?

Time:11-05

I have been wondering if calling the completion block from the request retry on the main queue, is ok, since the function call is made on the session.rootQueue

func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) {
    
        OperationQueue.main.addOperation { [weak self] in
            
            guard let self = self else {
                completion(.doNotRetryWithError(e))
                return
            }
            self.handleError(e, completion: completion)
            
        }
        
    }
    
}

the docu doesn't explicitly state that, but if i am not mistaken, it is generally expected to call completion blocks on the same queue as the function call was made

public protocol RequestRetrier {
    /// Determines whether the `Request` should be retried by calling the `completion` closure.
    ///
    /// This operation is fully asynchronous. Any amount of time can be taken to determine whether the request needs
    /// to be retried. The one requirement is that the completion closure is called to ensure the request is properly
    /// cleaned up after.
    ///
    /// - Parameters:
    ///   - request:    `Request` that failed due to the provided `Error`.
    ///   - session:    `Session` that produced the `Request`.
    ///   - error:      `Error` encountered while executing the `Request`.
    ///   - completion: Completion closure to be executed when a retry decision has been determined.
    func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void)

so my question is, on which queue should the completion be called?

CodePudding user response:

Yes, it's safe, as the internal implementation that calls your retrier immediately calls back onto Alamofire's rootQueue.

As of Alamofire 5.4.4:

retrier.retry(request, for: self, dueTo: error) { retryResult in
    self.rootQueue.async {
        guard let retryResultError = retryResult.error else { completion(retryResult); return }

        let retryError = AFError.requestRetryFailed(retryError: retryResultError, originalError:
error)
        completion(.doNotRetryWithError(retryError))
    }
}
  • Related