diff --git a/Package.swift b/Package.swift index 92c166a36..261d3f019 100644 --- a/Package.swift +++ b/Package.swift @@ -21,7 +21,7 @@ let package = Package( .library(name: "AsyncHTTPClient", targets: ["AsyncHTTPClient"]), ], dependencies: [ - .package(url: "https://github.com/apple/swift-nio.git", from: "2.18.0"), + .package(url: "https://github.com/apple/swift-nio.git", from: "2.19.0"), .package(url: "https://github.com/apple/swift-nio-ssl.git", from: "2.8.0"), .package(url: "https://github.com/apple/swift-nio-extras.git", from: "1.3.0"), .package(url: "https://github.com/apple/swift-nio-transport-services.git", from: "1.5.1"), diff --git a/Sources/AsyncHTTPClient/ConnectionPool.swift b/Sources/AsyncHTTPClient/ConnectionPool.swift index 5e44da8a9..1d04a24b7 100644 --- a/Sources/AsyncHTTPClient/ConnectionPool.swift +++ b/Sources/AsyncHTTPClient/ConnectionPool.swift @@ -353,7 +353,7 @@ class HTTP1ConnectionProvider { case .park(let connection): logger.trace("parking connection", metadata: ["ahc-connection": "\(connection)"]) - connection.setIdleTimeout(timeout: self.configuration.maximumAllowedIdleTimeInConnectionPool, + connection.setIdleTimeout(timeout: self.configuration.poolConfiguration.idleTimeout, logger: self.backgroundActivityLogger) case .closeProvider: logger.debug("closing provider", @@ -365,7 +365,7 @@ class HTTP1ConnectionProvider { logger.trace("parking connection & doing further action", metadata: ["ahc-connection": "\(connection)", "ahc-action": "\(action)"]) - connection.setIdleTimeout(timeout: self.configuration.maximumAllowedIdleTimeInConnectionPool, + connection.setIdleTimeout(timeout: self.configuration.poolConfiguration.idleTimeout, logger: self.backgroundActivityLogger) self.execute(action, logger: logger) case .closeAnd(let connection, let action): diff --git a/Sources/AsyncHTTPClient/HTTPClient.swift b/Sources/AsyncHTTPClient/HTTPClient.swift index aa4553eea..de2c5e551 100644 --- a/Sources/AsyncHTTPClient/HTTPClient.swift +++ b/Sources/AsyncHTTPClient/HTTPClient.swift @@ -641,8 +641,8 @@ public class HTTPClient { public var redirectConfiguration: RedirectConfiguration /// Default client timeout, defaults to no timeouts. public var timeout: Timeout - /// Timeout of pooled connections - public var maximumAllowedIdleTimeInConnectionPool: Optional + /// Connection pool configuration. + public var poolConfiguration: PoolConfiguration /// Upstream proxy, defaults to no proxy. public var proxy: Proxy? /// Enables automatic body decompression. Supported algorithms are gzip and deflate. @@ -653,14 +653,14 @@ public class HTTPClient { public init(tlsConfiguration: TLSConfiguration? = nil, redirectConfiguration: RedirectConfiguration? = nil, timeout: Timeout = Timeout(), - maximumAllowedIdleTimeInConnectionPool: TimeAmount, + poolConfiguration: PoolConfiguration = PoolConfiguration(), proxy: Proxy? = nil, ignoreUncleanSSLShutdown: Bool = false, decompression: Decompression = .disabled) { self.tlsConfiguration = tlsConfiguration self.redirectConfiguration = redirectConfiguration ?? RedirectConfiguration() self.timeout = timeout - self.maximumAllowedIdleTimeInConnectionPool = maximumAllowedIdleTimeInConnectionPool + self.poolConfiguration = poolConfiguration self.proxy = proxy self.ignoreUncleanSSLShutdown = ignoreUncleanSSLShutdown self.decompression = decompression @@ -676,7 +676,7 @@ public class HTTPClient { tlsConfiguration: tlsConfiguration, redirectConfiguration: redirectConfiguration, timeout: timeout, - maximumAllowedIdleTimeInConnectionPool: .seconds(60), + poolConfiguration: PoolConfiguration(), proxy: proxy, ignoreUncleanSSLShutdown: ignoreUncleanSSLShutdown, decompression: decompression @@ -693,7 +693,7 @@ public class HTTPClient { self.init(tlsConfiguration: TLSConfiguration.forClient(certificateVerification: certificateVerification), redirectConfiguration: redirectConfiguration, timeout: timeout, - maximumAllowedIdleTimeInConnectionPool: maximumAllowedIdleTimeInConnectionPool, + poolConfiguration: PoolConfiguration(), proxy: proxy, ignoreUncleanSSLShutdown: ignoreUncleanSSLShutdown, decompression: decompression) @@ -702,7 +702,7 @@ public class HTTPClient { public init(certificateVerification: CertificateVerification, redirectConfiguration: RedirectConfiguration? = nil, timeout: Timeout = Timeout(), - maximumAllowedIdleTimeInConnectionPool: TimeAmount = .seconds(60), + poolConfiguration: TimeAmount = .seconds(60), proxy: Proxy? = nil, ignoreUncleanSSLShutdown: Bool = false, decompression: Decompression = .disabled, @@ -710,7 +710,7 @@ public class HTTPClient { self.init(tlsConfiguration: TLSConfiguration.forClient(certificateVerification: certificateVerification), redirectConfiguration: redirectConfiguration, timeout: timeout, - maximumAllowedIdleTimeInConnectionPool: maximumAllowedIdleTimeInConnectionPool, + poolConfiguration: PoolConfiguration(), proxy: proxy, ignoreUncleanSSLShutdown: ignoreUncleanSSLShutdown, decompression: decompression) @@ -811,7 +811,7 @@ public class HTTPClient { } extension HTTPClient.Configuration { - /// Timeout configuration + /// Timeout configuration. public struct Timeout { /// Specifies connect timeout. public var connect: TimeAmount? @@ -860,6 +860,16 @@ extension HTTPClient.Configuration { /// - warning: Cycle detection will keep all visited URLs in memory which means a malicious server could use this as a denial-of-service vector. public static func follow(max: Int, allowCycles: Bool) -> RedirectConfiguration { return .init(configuration: .follow(max: max, allowCycles: allowCycles)) } } + + /// Connection pool configuration. + public struct PoolConfiguration: Hashable { + // Specifies amount of time connections are kept idle in the pool. + public var idleTimeout: TimeAmount + + public init(idleTimeout: TimeAmount = .seconds(60)) { + self.idleTimeout = idleTimeout + } + } } extension ChannelPipeline { diff --git a/Tests/AsyncHTTPClientTests/HTTPClientTests.swift b/Tests/AsyncHTTPClientTests/HTTPClientTests.swift index 6d611a679..1127dd394 100644 --- a/Tests/AsyncHTTPClientTests/HTTPClientTests.swift +++ b/Tests/AsyncHTTPClientTests/HTTPClientTests.swift @@ -1742,7 +1742,7 @@ class HTTPClientTests: XCTestCase { func testPoolClosesIdleConnections() { let localClient = HTTPClient(eventLoopGroupProvider: .shared(self.clientGroup), - configuration: .init(maximumAllowedIdleTimeInConnectionPool: .milliseconds(100))) + configuration: .init(poolConfiguration: .init(idleTimeout: .milliseconds(100)))) defer { XCTAssertNoThrow(try localClient.syncShutdown()) } @@ -1753,7 +1753,7 @@ class HTTPClientTests: XCTestCase { func testRacePoolIdleConnectionsAndGet() { let localClient = HTTPClient(eventLoopGroupProvider: .shared(self.clientGroup), - configuration: .init(maximumAllowedIdleTimeInConnectionPool: .milliseconds(10))) + configuration: .init(poolConfiguration: .init(idleTimeout: .milliseconds(10)))) defer { XCTAssertNoThrow(try localClient.syncShutdown()) }