mirror of
https://github.com/swift-server/async-http-client.git
synced 2026-05-03 07:32:29 +00:00
Add an HTTP/1.1 connection pool (#105)
motivation: Better performance thanks to connection reuse changes: - Added a connection pool for HTTP/1.1 - All requests automatically use the connection pool - Up to 8 parallel connections per (scheme, host, port) - Multiple additional unit tests
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
|
||||
import NIO
|
||||
import NIOHTTP1
|
||||
import NIOHTTPCompression
|
||||
|
||||
internal extension String {
|
||||
var isIPAddress: Bool {
|
||||
@@ -44,3 +45,53 @@ public final class HTTPClientCopyingDelegate: HTTPClientResponseDelegate {
|
||||
return ()
|
||||
}
|
||||
}
|
||||
|
||||
extension ClientBootstrap {
|
||||
static func makeHTTPClientBootstrapBase(group: EventLoopGroup, host: String, port: Int, configuration: HTTPClient.Configuration, channelInitializer: ((Channel) -> EventLoopFuture<Void>)? = nil) -> ClientBootstrap {
|
||||
return ClientBootstrap(group: group)
|
||||
.channelOption(ChannelOptions.socket(SocketOptionLevel(IPPROTO_TCP), TCP_NODELAY), value: 1)
|
||||
|
||||
.channelInitializer { channel in
|
||||
let channelAddedFuture: EventLoopFuture<Void>
|
||||
switch configuration.proxy {
|
||||
case .none:
|
||||
channelAddedFuture = group.next().makeSucceededFuture(())
|
||||
case .some:
|
||||
channelAddedFuture = channel.pipeline.addProxyHandler(host: host, port: port, authorization: configuration.proxy?.authorization)
|
||||
}
|
||||
return channelAddedFuture.flatMap { (_: Void) -> EventLoopFuture<Void> in
|
||||
channelInitializer?(channel) ?? group.next().makeSucceededFuture(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension CircularBuffer {
|
||||
@discardableResult
|
||||
mutating func swapWithFirstAndRemove(at index: Index) -> Element? {
|
||||
precondition(index >= self.startIndex && index < self.endIndex)
|
||||
if !self.isEmpty {
|
||||
self.swapAt(self.startIndex, index)
|
||||
return self.removeFirst()
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
mutating func swapWithFirstAndRemove(where predicate: (Element) throws -> Bool) rethrows -> Element? {
|
||||
if let existingIndex = try self.firstIndex(where: predicate) {
|
||||
return self.swapWithFirstAndRemove(at: existingIndex)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ConnectionPool.Connection {
|
||||
func removeHandler<Handler: RemovableChannelHandler>(_ type: Handler.Type) -> EventLoopFuture<Void> {
|
||||
return self.channel.pipeline.handler(type: type).flatMap { handler in
|
||||
self.channel.pipeline.removeHandler(handler)
|
||||
}.recover { _ in }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user