@@ -78,6 +78,7 @@ public class HTTPClient {
7878
7979 private var state : State
8080 private let stateLock = NIOLock ( )
81+ private let canBeShutDown : Bool
8182
8283 internal static let loggingDisabled = Logger ( label: " AHC-do-not-log " , factory: { _ in SwiftLogNoOpLogHandler ( ) } )
8384
@@ -133,9 +134,20 @@ public class HTTPClient {
133134 /// - eventLoopGroup: The `EventLoopGroup` that the ``HTTPClient`` will use.
134135 /// - configuration: Client configuration.
135136 /// - 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
139151 self . eventLoopGroup = eventLoopGroup
140152 self . configuration = configuration
141153 self . poolManager = HTTPConnectionPool . Manager (
@@ -247,6 +259,12 @@ public class HTTPClient {
247259 }
248260
249261 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+ }
250268 do {
251269 try self . stateLock. withLock {
252270 guard case . upAndRunning = self . state else {
@@ -1069,6 +1087,7 @@ public struct HTTPClientError: Error, Equatable, CustomStringConvertible {
10691087 case getConnectionFromPoolTimeout
10701088 case deadlineExceeded
10711089 case httpEndReceivedAfterHeadWith1xx
1090+ case shutdownUnsupported
10721091 }
10731092
10741093 private var code : Code
@@ -1150,6 +1169,8 @@ public struct HTTPClientError: Error, Equatable, CustomStringConvertible {
11501169 return " Deadline exceeded "
11511170 case . httpEndReceivedAfterHeadWith1xx:
11521171 return " HTTP end received after head with 1xx "
1172+ case . shutdownUnsupported:
1173+ return " The global singleton HTTP client cannot be shut down "
11531174 }
11541175 }
11551176
@@ -1213,6 +1234,10 @@ public struct HTTPClientError: Error, Equatable, CustomStringConvertible {
12131234 public static func serverOfferedUnsupportedApplicationProtocol( _ proto: String ) -> HTTPClientError {
12141235 return HTTPClientError ( code: . serverOfferedUnsupportedApplicationProtocol( proto) )
12151236 }
1237+ /// The globally shared singleton ``HTTPClient`` cannot be shut down.
1238+ public static var shutdownUnsupported : HTTPClientError {
1239+ return HTTPClientError ( code: . shutdownUnsupported)
1240+ }
12161241
12171242 /// The request deadline was exceeded. The request was cancelled because of this.
12181243 public static let deadlineExceeded = HTTPClientError ( code: . deadlineExceeded)
0 commit comments