@@ -236,6 +236,9 @@ extension HTTPConnectionPool {
236
236
237
237
mutating func http2ConnectionClosed( _ connectionID: Connection . ID ) -> Action {
238
238
guard let ( index, context) = self . connections. failConnection ( connectionID) else {
239
+ // When a connection close is initiated by the connection pool, the connection will
240
+ // still report its close to the state machine. In those cases we must ignore the
241
+ // event.
239
242
return . none
240
243
}
241
244
return self . nextActionForFailedConnection ( at: index, on: context. eventLoop)
@@ -367,17 +370,52 @@ extension HTTPConnectionPool {
367
370
}
368
371
369
372
mutating func connectionClosed( _ connectionID: Connection . ID ) -> Action {
370
- guard let ( index, context) = self . connections. failConnection ( connectionID) else {
371
- // When a connection close is initiated by the connection pool, the connection will
372
- // still report its close to the state machine. In those cases we must ignore the
373
- // event.
373
+ guard let index = self . http1Connections? . failConnection ( connectionID) ? . 0 else {
374
374
return . none
375
375
}
376
- return self . nextActionForFailedConnection ( at: index, on: context. eventLoop)
376
+ self . http1Connections!. removeConnection ( at: index)
377
+ if self . http1Connections!. isEmpty {
378
+ self . http1Connections = nil
379
+ }
380
+ switch state {
381
+ case . running:
382
+ return . none
383
+ case . shuttingDown( let unclean) :
384
+ if self . http1Connections == nil && self . connections. isEmpty {
385
+ return . init(
386
+ request: . none,
387
+ connection: . cleanupConnections( . init( ) , isShutdown: . yes( unclean: unclean) )
388
+ )
389
+ } else {
390
+ return . none
391
+ }
392
+ case . shutDown:
393
+ preconditionFailure ( " If the pool is already shutdown, all connections must have been torn down. " )
394
+ }
377
395
}
378
396
379
- mutating func http1ConnectionReleased( _: Connection . ID ) -> Action {
380
- fatalError ( " TODO: implement \( #function) " )
397
+ mutating func http1ConnectionReleased( _ connectionID: Connection . ID ) -> Action {
398
+ // It is save to bang the http1Connections here. If we get this callback but we don't have
399
+ // http1 connections something has gone terribly wrong.
400
+ let ( index, _) = self . http1Connections!. releaseConnection ( connectionID)
401
+ // Any http1 connection that becomes idle should be closed right away after the transition
402
+ // to http2.
403
+ let connection = self . http1Connections!. closeConnection ( at: index)
404
+ if self . http1Connections!. isEmpty {
405
+ self . http1Connections = nil
406
+ }
407
+ switch state {
408
+ case . running:
409
+ return . init( request: . none, connection: . closeConnection( connection, isShutdown: . no) )
410
+ case . shuttingDown( let unclean) :
411
+ if self . http1Connections == nil && self . connections. isEmpty {
412
+ return . init( request: . none, connection: . closeConnection( connection, isShutdown: . yes( unclean: unclean) ) )
413
+ } else {
414
+ return . init( request: . none, connection: . closeConnection( connection, isShutdown: . no) )
415
+ }
416
+ case . shutDown:
417
+ preconditionFailure ( " If the pool is already shutdown, all connections must have been torn down. " )
418
+ }
381
419
}
382
420
383
421
mutating func shutdown( ) -> Action {
0 commit comments