Repository: Alamofire/Alamofire
File: Source/Request.swift (Swift)

Code before:
    ///   - queue:   The `DispatchQueue` to execute the closure on. Defaults to `.main`.
    ///   - closure: The closure to be executed periodically as data is sent to the server.
    /// - Returns:   The `Request`.
    @discardableResult
    open func uploadProgress(queue: DispatchQueue = .main, closure: @escaping ProgressHandler) -> Self {
        protectedMutableState.write { $0.uploadProgressHandler = (handler: closure, queue: queue) }

        return self
    }

    // MARK: - Redirects

    /// Sets the redirect handler for the `Request` which will be used if a redirect response is encountered.
    ///
    /// - Parameter handler: The redirect handler.
    /// - Returns: The `Request`.
    @discardableResult
    open func redirect(with handler: RedirectHandler) -> Self {
        protectedMutableState.write { $0.redirectHandler = handler }
        return self
    }

    // MARK: - Cached Responses

    @discardableResult
    open func cacheResponse(with handler: CachedResponseHandler) -> Self {
        protectedMutableState.write { $0.cachedResponseHandler = handler }
        return self
    }
}

// MARK: - Protocol Conformances

extension Request: Equatable {
    public static func == (lhs: Request, rhs: Request) -> Bool {
        return lhs.id == rhs.id
    }
}

extension Request: Hashable {
    public var hashValue: Int {
        return id.hashValue
    }
}

extension Request: CustomStringConvertible {
    /// A textual representation of this instance, including the `HTTPMethod` and `URL` if the `URLRequest` has been
    /// created, as well as the response status code, if a response has been received.
    public var description: String {
        guard let request = performedRequests.last ?? lastRequest,
            let url = request.url,

Review comment (performance):
I prefer `using` as the modifier for methods like this. e.g. `.cacheResponse(using: myHandler)`.

Code after:
        return self
    }

    // MARK: - Redirects

    /// Sets the redirect handler for the `Request` which will be used if a redirect response is encountered.
    ///
    /// - Parameter handler: The `RedirectHandler`.
    /// - Returns:           The `Request`.
    @discardableResult
    open func redirect(using handler: RedirectHandler) -> Self {
        protectedMutableState.write { mutableState in
            precondition(mutableState.redirectHandler == nil, "Redirect handler has already been set")
            mutableState.redirectHandler = handler
        }

        return self
    }

    // MARK: - Cached Responses

    /// Sets the cached response handler for the `Request` which will be used when attempting to cache a response.
    ///
    /// - Parameter handler: The `CachedResponseHandler`.
    /// - Returns:           The `Request`.
    @discardableResult
    open func cacheResponse(using handler: CachedResponseHandler) -> Self {
        protectedMutableState.write { mutableState in
            precondition(mutableState.cachedResponseHandler == nil, "Cached response handler has already been set")
            mutableState.cachedResponseHandler = handler
        }

        return self
    }
}

// MARK: - Protocol Conformances

extension Request: Equatable {
    public static func == (lhs: Request, rhs: Request) -> Bool {
        return lhs.id == rhs.id
    }
}

extension Request: Hashable {
    public var hashValue: Int {
        return id.hashValue
    }
}

extension Request: CustomStringConvertible {