@@ -78,6 +78,7 @@ public class HTTPClient {
78
78
79
79
private var state : State
80
80
private let stateLock = NIOLock ( )
81
+ private let canBeShutDown : Bool
81
82
82
83
internal static let loggingDisabled = Logger ( label: " AHC-do-not-log " , factory: { _ in SwiftLogNoOpLogHandler ( ) } )
83
84
@@ -133,9 +134,20 @@ public class HTTPClient {
133
134
/// - eventLoopGroup: The `EventLoopGroup` that the ``HTTPClient`` will use.
134
135
/// - configuration: Client configuration.
135
136
/// - backgroundActivityLogger: The `Logger` that will be used to log background any activity that's not associated with a request.
136
- public required init ( eventLoopGroup: any EventLoopGroup ,
137
- configuration: Configuration = Configuration ( ) ,
138
- backgroundActivityLogger: Logger ) {
137
+ public convenience init ( eventLoopGroup: any EventLoopGroup ,
138
+ configuration: Configuration = Configuration ( ) ,
139
+ backgroundActivityLogger: Logger ) {
140
+ self . init ( eventLoopGroup: eventLoopGroup,
141
+ configuration: configuration,
142
+ backgroundActivityLogger: backgroundActivityLogger,
143
+ canBeShutDown: true )
144
+ }
145
+
146
+ internal required init ( eventLoopGroup: EventLoopGroup ,
147
+ configuration: Configuration = Configuration ( ) ,
148
+ backgroundActivityLogger: Logger ,
149
+ canBeShutDown: Bool ) {
150
+ self . canBeShutDown = canBeShutDown
139
151
self . eventLoopGroup = eventLoopGroup
140
152
self . configuration = configuration
141
153
self . poolManager = HTTPConnectionPool . Manager (
@@ -247,6 +259,12 @@ public class HTTPClient {
247
259
}
248
260
249
261
private func shutdown( requiresCleanClose: Bool , queue: DispatchQueue , _ callback: @escaping ShutdownCallback ) {
262
+ guard self . canBeShutDown else {
263
+ queue. async {
264
+ callback ( HTTPClientError . shutdownUnsupported)
265
+ }
266
+ return
267
+ }
250
268
do {
251
269
try self . stateLock. withLock {
252
270
guard case . upAndRunning = self . state else {
@@ -1069,6 +1087,7 @@ public struct HTTPClientError: Error, Equatable, CustomStringConvertible {
1069
1087
case getConnectionFromPoolTimeout
1070
1088
case deadlineExceeded
1071
1089
case httpEndReceivedAfterHeadWith1xx
1090
+ case shutdownUnsupported
1072
1091
}
1073
1092
1074
1093
private var code : Code
@@ -1150,6 +1169,8 @@ public struct HTTPClientError: Error, Equatable, CustomStringConvertible {
1150
1169
return " Deadline exceeded "
1151
1170
case . httpEndReceivedAfterHeadWith1xx:
1152
1171
return " HTTP end received after head with 1xx "
1172
+ case . shutdownUnsupported:
1173
+ return " The global singleton HTTP client cannot be shut down "
1153
1174
}
1154
1175
}
1155
1176
@@ -1214,6 +1235,11 @@ public struct HTTPClientError: Error, Equatable, CustomStringConvertible {
1214
1235
return HTTPClientError ( code: . serverOfferedUnsupportedApplicationProtocol( proto) )
1215
1236
}
1216
1237
1238
+ /// The globally shared singleton ``HTTPClient`` cannot be shut down.
1239
+ public static var shutdownUnsupported : HTTPClientError {
1240
+ return HTTPClientError ( code: . shutdownUnsupported)
1241
+ }
1242
+
1217
1243
/// The request deadline was exceeded. The request was cancelled because of this.
1218
1244
public static let deadlineExceeded = HTTPClientError ( code: . deadlineExceeded)
1219
1245
0 commit comments