@@ -134,19 +134,6 @@ extension PoolStateMachine {
134
134
var info : ConnectionAvailableInfo
135
135
}
136
136
137
- /// Information around the failed/closed connection.
138
- @usableFromInline
139
- struct FailedConnectionContext {
140
- /// Connections that are currently starting
141
- @usableFromInline
142
- var connectionsStarting : Int
143
-
144
- @inlinable
145
- init ( connectionsStarting: Int ) {
146
- self . connectionsStarting = connectionsStarting
147
- }
148
- }
149
-
150
137
mutating func refillConnections( ) -> [ ConnectionRequest ] {
151
138
let existingConnections = self . stats. active
152
139
let missingConnection = self . minimumConcurrentConnections - Int( existingConnections)
@@ -477,6 +464,31 @@ extension PoolStateMachine {
477
464
return self . closeConnectionIfIdle ( at: index)
478
465
}
479
466
467
+ /// Information around the failed/closed connection.
468
+ @usableFromInline
469
+ struct ClosedAction {
470
+ /// Connections that are currently starting
471
+ @usableFromInline
472
+ var connectionsStarting : Int
473
+
474
+ @usableFromInline
475
+ var timersToCancel : TinyFastSequence < TimerCancellationToken >
476
+
477
+ @usableFromInline
478
+ var newConnectionRequest : ConnectionRequest ?
479
+
480
+ @inlinable
481
+ init (
482
+ connectionsStarting: Int ,
483
+ timersToCancel: TinyFastSequence < TimerCancellationToken > ,
484
+ newConnectionRequest: ConnectionRequest ? = nil
485
+ ) {
486
+ self . connectionsStarting = connectionsStarting
487
+ self . timersToCancel = timersToCancel
488
+ self . newConnectionRequest = newConnectionRequest
489
+ }
490
+ }
491
+
480
492
/// Connection closed. Call this method, if a connection is closed.
481
493
///
482
494
/// This will put the position into the closed state.
@@ -487,12 +499,13 @@ extension PoolStateMachine {
487
499
/// supplied index after this. If nil is returned the connection was closed by the state machine and was
488
500
/// therefore already removed.
489
501
@inlinable
490
- mutating func connectionClosed( _ connectionID: Connection . ID ) -> FailedConnectionContext ? {
502
+ mutating func connectionClosed( _ connectionID: Connection . ID ) -> ClosedAction {
491
503
guard let index = self . connections. firstIndex ( where: { $0. id == connectionID } ) else {
492
- return nil
504
+ preconditionFailure ( " All connections that have been created should say goodbye exactly once! " )
493
505
}
494
506
495
507
let closedAction = self . connections [ index] . closed ( )
508
+ var timersToCancel = TinyFastSequence ( closedAction. cancelTimers)
496
509
497
510
if closedAction. wasRunningKeepAlive {
498
511
self . stats. runningKeepAlive -= 1
@@ -511,16 +524,22 @@ extension PoolStateMachine {
511
524
self . stats. closing -= 1
512
525
}
513
526
514
- let lastIndex = self . connections. index ( before: self . connections. endIndex)
527
+ if let cancellationTimer = self . swapForDeletion ( index: index) {
528
+ timersToCancel. append ( cancellationTimer)
529
+ }
515
530
516
- if index == lastIndex {
517
- self . connections. remove ( at: index)
531
+ let newConnectionRequest : ConnectionRequest ?
532
+ if self . connections. count < self . minimumConcurrentConnections {
533
+ newConnectionRequest = . init( connectionID: self . generator. next ( ) )
518
534
} else {
519
- self . connections. swapAt ( index, lastIndex)
520
- self . connections. remove ( at: lastIndex)
535
+ newConnectionRequest = . none
521
536
}
522
537
523
- return FailedConnectionContext ( connectionsStarting: 0 )
538
+ return ClosedAction (
539
+ connectionsStarting: 0 ,
540
+ timersToCancel: timersToCancel,
541
+ newConnectionRequest: newConnectionRequest
542
+ )
524
543
}
525
544
526
545
// MARK: Shutdown
0 commit comments