From eef7478c32cd8d7d037fd9a9f62d93e6264299ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Fontana?= Date: Sun, 19 Mar 2023 18:56:12 +0100 Subject: [PATCH 1/2] Feat: add custom retry strategy implementation Closes #79 --- Documentation/3.Advanced_HTTPClient.md | 1 + .../Internal/HTTPResponseValidator/HTTPValidator.swift | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/Documentation/3.Advanced_HTTPClient.md b/Documentation/3.Advanced_HTTPClient.md index 5510a99..c23fb9d 100644 --- a/Documentation/3.Advanced_HTTPClient.md +++ b/Documentation/3.Advanced_HTTPClient.md @@ -77,6 +77,7 @@ The options are: - `exponential` and `fibonacci` are the same as `delayed`, but with sequentially increasing delay times - `after(HTTPRequest, TimeInterval, AltRequestCatcher?)` will retry the original call after calling an alternate request. For example, if you are making an authenticated request and the session has expired; you can then call a login alternate request to perform a new login and retry the original call. - `afterTask(TimeInterval, RetryTask, RetryTaskErrorCatcher?)` performs an async task before retrying the original request. By using an async `Task`, you may perform work outside of the scope of RealHTTP and inject whatever you need into the original request. Note that, like with the existing retry with `HTTPRequest` strategy, any error triggered by the async `Task` is not propagated to the original request. However, a callback could be provided to at least "see" it. +- `custom` will retry the original call after the amount of seconds returned by the closure you are required to provide for this case. The closure provides you with the failed `HTTPRequest` object so you have the chance to define any custom logic based on it and return the desired amount of seconds. We'll take a closer look at these strategies below. diff --git a/Sources/RealHTTP/Client/Internal/HTTPResponseValidator/HTTPValidator.swift b/Sources/RealHTTP/Client/Internal/HTTPResponseValidator/HTTPValidator.swift index d18aff4..d290b03 100644 --- a/Sources/RealHTTP/Client/Internal/HTTPResponseValidator/HTTPValidator.swift +++ b/Sources/RealHTTP/Client/Internal/HTTPResponseValidator/HTTPValidator.swift @@ -63,6 +63,7 @@ public enum HTTPRetryStrategy { public typealias AltRequestCatcher = ((_ request: HTTPRequest, _ response: HTTPResponse) async throws -> Void) public typealias RetryTask = ((_ originalRequest: HTTPRequest) async throws -> Void) public typealias RetryTaskErrorCatcher = ((_ error: Error) async -> Void) + public typealias CustomRetryIntervalProvider = (_ request: HTTPRequest) -> TimeInterval case immediate case delayed(_ interval: TimeInterval) @@ -70,6 +71,7 @@ public enum HTTPRetryStrategy { case fibonacci case after(HTTPRequest, TimeInterval, AltRequestCatcher?) case afterTask(TimeInterval, RetryTask, RetryTaskErrorCatcher?) + case custom(_ retryIntervalProvider: CustomRetryIntervalProvider) // MARK: - Internal Functions @@ -108,6 +110,9 @@ public enum HTTPRetryStrategy { case .afterTask: return 0 + + case .custom(let retryIntervalProvider): + return retryIntervalProvider(request) } } From 347f5b727a5c56712c4ba8919abf2f295acdc73b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Fontana?= Date: Sun, 19 Mar 2023 19:05:24 +0100 Subject: [PATCH 2/2] Doc: add HTTPRetryStrategy `custom` case documentation --- .../Client/Internal/HTTPResponseValidator/HTTPValidator.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/RealHTTP/Client/Internal/HTTPResponseValidator/HTTPValidator.swift b/Sources/RealHTTP/Client/Internal/HTTPResponseValidator/HTTPValidator.swift index d290b03..44621c3 100644 --- a/Sources/RealHTTP/Client/Internal/HTTPResponseValidator/HTTPValidator.swift +++ b/Sources/RealHTTP/Client/Internal/HTTPResponseValidator/HTTPValidator.swift @@ -59,6 +59,8 @@ public enum HTTPResponseValidatorResult { /// - the request you want to execute before retry the original request. /// - the amount of time before retry the original request once you got the response for the alt request. /// - an optional async callback to execute once you got the response of the alt request before retry the original request. +/// - `custom` will retry the original call after the amount of seconds returned by the closure you are required to provide for this case. +/// The closure provides you with the failed `HTTPRequest` object so you have the chance to define any custom logic based on it and return the desired amount of seconds. public enum HTTPRetryStrategy { public typealias AltRequestCatcher = ((_ request: HTTPRequest, _ response: HTTPResponse) async throws -> Void) public typealias RetryTask = ((_ originalRequest: HTTPRequest) async throws -> Void)