@@ -49,20 +49,6 @@ extension HTTPConnectionPool {
4949 self . connections = HTTP2Connections ( generator: idGenerator)
5050 }
5151
52- mutating func migrateFromHTTP1(
53- http1State: HTTP1StateMachine ,
54- newHTTP2Connection: Connection ,
55- maxConcurrentStreams: Int
56- ) -> Action {
57- self . migrateFromHTTP1 (
58- http1Connections: http1State. connections,
59- http2Connections: http1State. http2Connections,
60- requests: http1State. requests,
61- newHTTP2Connection: newHTTP2Connection,
62- maxConcurrentStreams: maxConcurrentStreams
63- )
64- }
65-
6652 mutating func migrateFromHTTP1(
6753 http1Connections: HTTP1Connections ,
6854 http2Connections: HTTP2Connections ? = nil ,
@@ -228,11 +214,22 @@ extension HTTPConnectionPool {
228214 private mutating func _newHTTP2ConnectionEstablished( _ connection: Connection , maxConcurrentStreams: Int ) -> EstablishedAction {
229215 self . failedConsecutiveConnectionAttempts = 0
230216 self . lastConnectFailure = nil
231- let ( index, context) = self . connections. newHTTP2ConnectionEstablished (
232- connection,
233- maxConcurrentStreams: maxConcurrentStreams
234- )
235- return self . nextActionForAvailableConnection ( at: index, context: context)
217+ if self . connections. hasActiveConnection ( for: connection. eventLoop) {
218+ guard let ( index, _) = self . connections. failConnection ( connection. id) else {
219+ preconditionFailure ( " we have established a new connection that we know nothing about? " )
220+ }
221+ self . connections. removeConnection ( at: index)
222+ return . init(
223+ request: . none,
224+ connection: . closeConnection( connection, isShutdown: . no)
225+ )
226+ } else {
227+ let ( index, context) = self . connections. newHTTP2ConnectionEstablished (
228+ connection,
229+ maxConcurrentStreams: maxConcurrentStreams
230+ )
231+ return self . nextActionForAvailableConnection ( at: index, context: context)
232+ }
236233 }
237234
238235 private mutating func nextActionForAvailableConnection(
@@ -318,8 +315,28 @@ extension HTTPConnectionPool {
318315 private mutating func nextActionForFailedConnection( at index: Int , on eventLoop: EventLoop ) -> Action {
319316 switch self . state {
320317 case . running:
321- let hasPendingRequest = !self . requests. isEmpty ( for: eventLoop) || !self . requests. isEmpty ( for: nil )
322- guard hasPendingRequest else {
318+ // we do not know if we have created this connection for a request with a required
319+ // event loop or not. However, we do not need this information and can infer
320+ // if we need to create a new connection because we will only ever create one connection
321+ // per event loop for required event loop requests and only need one connection for
322+ // general purpose requests.
323+
324+ // we need to start a new on connection in two cases:
325+ let needGeneralPurposeConnection =
326+ // 1. if we have general purpose requests
327+ !self . requests. isEmpty ( for: nil ) &&
328+ // and no connection starting or active
329+ !self . connections. hasStartingOrActiveConnection ( )
330+
331+ let needRequiredEventLoopConnection =
332+ // 2. or if we have requests for a required event loop
333+ !self . requests. isEmpty ( for: eventLoop) &&
334+ // and no connection starting or active for the given event loop
335+ !self . connections. hasStartingOrActiveConnection ( for: eventLoop)
336+
337+ guard needGeneralPurposeConnection || needRequiredEventLoopConnection else {
338+ // otherwise we can remove the connection
339+ self . connections. removeConnection ( at: index)
323340 return . none
324341 }
325342
@@ -330,6 +347,7 @@ extension HTTPConnectionPool {
330347 request: . none,
331348 connection: . createConnection( newConnectionID, on: eventLoop)
332349 )
350+
333351 case . shuttingDown( let unclean) :
334352 assert ( self . requests. isEmpty)
335353 self . connections. removeConnection ( at: index)
0 commit comments