@@ -33,8 +33,11 @@ public protocol HTTPClientProtocol {
33
33
///
34
34
/// - Parameters:
35
35
/// - request: The `HTTPClientRequest` to perform.
36
+ /// - observabilityScope: the observability scope to emit diagnostics on
37
+ /// - progress: A closure to handle progress for example for downloads
36
38
/// - callback: A closure to be notified of the completion of the request.
37
39
func execute( _ request: HTTPClientRequest ,
40
+ observabilityScope: ObservabilityScope ? ,
38
41
progress: ProgressHandler ? ,
39
42
completion: @escaping CompletionHandler )
40
43
}
@@ -56,21 +59,19 @@ public struct HTTPClient: HTTPClientProtocol {
56
59
public typealias Handler = ( Request , ProgressHandler ? , @escaping ( Result < Response , Error > ) -> Void ) -> Void
57
60
58
61
public var configuration : HTTPClientConfiguration
59
- private let observabilityScope : ObservabilityScope
60
62
private let underlying : Handler
61
63
62
64
// static to share across instances of the http client
63
65
private static var hostsErrorsLock = Lock ( )
64
66
private static var hostsErrors = [ String: [ Date] ] ( )
65
67
66
- public init ( configuration: HTTPClientConfiguration = . init( ) , handler: Handler ? = nil , observabilityScope : ObservabilityScope = ObservabilitySystem . topScope ) {
68
+ public init ( configuration: HTTPClientConfiguration = . init( ) , handler: Handler ? = nil ) {
67
69
self . configuration = configuration
68
- self . observabilityScope = observabilityScope
69
70
// FIXME: inject platform specific implementation here
70
71
self . underlying = handler ?? URLSessionHTTPClient ( ) . execute
71
72
}
72
73
73
- public func execute( _ request: Request , progress: ProgressHandler ? = nil , completion: @escaping CompletionHandler ) {
74
+ public func execute( _ request: Request , observabilityScope : ObservabilityScope ? = nil , progress: ProgressHandler ? = nil , completion: @escaping CompletionHandler ) {
74
75
// merge configuration
75
76
var request = request
76
77
if request. options. callbackQueue == nil {
@@ -103,7 +104,9 @@ public struct HTTPClient: HTTPClientProtocol {
103
104
// execute
104
105
let callbackQueue = request. options. callbackQueue ?? self . configuration. callbackQueue
105
106
self . _execute (
106
- request: request, requestNumber: 0 ,
107
+ request: request,
108
+ requestNumber: 0 ,
109
+ observabilityScope: observabilityScope,
107
110
progress: progress. map { handler in
108
111
{ received, expected in
109
112
callbackQueue. async {
@@ -119,9 +122,9 @@ public struct HTTPClient: HTTPClientProtocol {
119
122
)
120
123
}
121
124
122
- private func _execute( request: Request , requestNumber: Int , progress: ProgressHandler ? , completion: @escaping CompletionHandler ) {
125
+ private func _execute( request: Request , requestNumber: Int , observabilityScope : ObservabilityScope ? , progress: ProgressHandler ? , completion: @escaping CompletionHandler ) {
123
126
if self . shouldCircuitBreak ( request: request) {
124
- self . observabilityScope. emit ( warning: " Circuit breaker triggered for \( request. url) " )
127
+ observabilityScope? . emit ( warning: " Circuit breaker triggered for \( request. url) " )
125
128
return completion ( . failure( HTTPClientError . circuitBreakerTriggered) )
126
129
}
127
130
@@ -145,10 +148,10 @@ public struct HTTPClient: HTTPClientProtocol {
145
148
self . recordErrorIfNecessary ( response: response, request: request)
146
149
// handle retry strategy
147
150
if let retryDelay = self . shouldRetry ( response: response, request: request, requestNumber: requestNumber) {
148
- self . observabilityScope. emit ( warning: " \( request. url) failed, retrying in \( retryDelay) " )
151
+ observabilityScope? . emit ( warning: " \( request. url) failed, retrying in \( retryDelay) " )
149
152
// TODO: dedicated retry queue?
150
153
return self . configuration. callbackQueue. asyncAfter ( deadline: . now( ) + retryDelay) {
151
- self . _execute ( request: request, requestNumber: requestNumber + 1 , progress: progress, completion: completion)
154
+ self . _execute ( request: request, requestNumber: requestNumber + 1 , observabilityScope : observabilityScope , progress: progress, completion: completion)
152
155
}
153
156
}
154
157
// check for valid response codes
@@ -220,24 +223,24 @@ public struct HTTPClient: HTTPClientProtocol {
220
223
}
221
224
222
225
public extension HTTPClient {
223
- func head( _ url: URL , headers: HTTPClientHeaders = . init( ) , options: Request . Options = . init( ) , completion: @escaping ( Result < Response , Error > ) -> Void ) {
224
- self . execute ( Request ( method: . head, url: url, headers: headers, body: nil , options: options) , completion: completion)
226
+ func head( _ url: URL , headers: HTTPClientHeaders = . init( ) , options: Request . Options = . init( ) , observabilityScope : ObservabilityScope ? = . none , completion: @escaping ( Result < Response , Error > ) -> Void ) {
227
+ self . execute ( Request ( method: . head, url: url, headers: headers, body: nil , options: options) , observabilityScope : observabilityScope , completion: completion)
225
228
}
226
229
227
- func get( _ url: URL , headers: HTTPClientHeaders = . init( ) , options: Request . Options = . init( ) , completion: @escaping ( Result < Response , Error > ) -> Void ) {
228
- self . execute ( Request ( method: . get, url: url, headers: headers, body: nil , options: options) , completion: completion)
230
+ func get( _ url: URL , headers: HTTPClientHeaders = . init( ) , options: Request . Options = . init( ) , observabilityScope : ObservabilityScope ? = . none , completion: @escaping ( Result < Response , Error > ) -> Void ) {
231
+ self . execute ( Request ( method: . get, url: url, headers: headers, body: nil , options: options) , observabilityScope : observabilityScope , completion: completion)
229
232
}
230
233
231
- func put( _ url: URL , body: Data ? , headers: HTTPClientHeaders = . init( ) , options: Request . Options = . init( ) , completion: @escaping ( Result < Response , Error > ) -> Void ) {
232
- self . execute ( Request ( method: . put, url: url, headers: headers, body: body, options: options) , completion: completion)
234
+ func put( _ url: URL , body: Data ? , headers: HTTPClientHeaders = . init( ) , options: Request . Options = . init( ) , observabilityScope : ObservabilityScope ? = . none , completion: @escaping ( Result < Response , Error > ) -> Void ) {
235
+ self . execute ( Request ( method: . put, url: url, headers: headers, body: body, options: options) , observabilityScope : observabilityScope , completion: completion)
233
236
}
234
237
235
- func post( _ url: URL , body: Data ? , headers: HTTPClientHeaders = . init( ) , options: Request . Options = . init( ) , completion: @escaping ( Result < Response , Error > ) -> Void ) {
236
- self . execute ( Request ( method: . post, url: url, headers: headers, body: body, options: options) , completion: completion)
238
+ func post( _ url: URL , body: Data ? , headers: HTTPClientHeaders = . init( ) , options: Request . Options = . init( ) , observabilityScope : ObservabilityScope ? = . none , completion: @escaping ( Result < Response , Error > ) -> Void ) {
239
+ self . execute ( Request ( method: . post, url: url, headers: headers, body: body, options: options) , observabilityScope : observabilityScope , completion: completion)
237
240
}
238
241
239
- func delete( _ url: URL , headers: HTTPClientHeaders = . init( ) , options: Request . Options = . init( ) , completion: @escaping ( Result < Response , Error > ) -> Void ) {
240
- self . execute ( Request ( method: . delete, url: url, headers: headers, body: nil , options: options) , completion: completion)
242
+ func delete( _ url: URL , headers: HTTPClientHeaders = . init( ) , options: Request . Options = . init( ) , observabilityScope : ObservabilityScope ? = . none , completion: @escaping ( Result < Response , Error > ) -> Void ) {
243
+ self . execute ( Request ( method: . delete, url: url, headers: headers, body: nil , options: options) , observabilityScope : observabilityScope , completion: completion)
241
244
}
242
245
}
243
246
0 commit comments