Current code assumes that we are always in the running state. We therefore never transition from the shuttingDown
to the shutDown
state if the last connection in the pool fails.
|
mutating func failedToCreateNewConnection(_ error: Error, connectionID: Connection.ID) -> Action { |
|
self.failedConsecutiveConnectionAttempts += 1 |
|
self.lastConnectFailure = error |
|
|
|
let eventLoop = self.connections.backoffNextConnectionAttempt(connectionID) |
|
let backoff = calculateBackoff(failedAttempt: self.failedConsecutiveConnectionAttempts) |
|
return .init(request: .none, connection: .scheduleBackoffTimer(connectionID, backoff: backoff, on: eventLoop)) |
|
} |
We likely need to do something similar to the
HTTP1StateMachine
.
|
mutating func failedToCreateNewConnection(_ error: Error, connectionID: Connection.ID) -> Action { |
|
self.failedConsecutiveConnectionAttempts += 1 |
|
self.lastConnectFailure = error |
|
|
|
switch self.lifecycleState { |
|
case .running: |
|
// We don't care how many waiting requests we have at this point, we will schedule a |
|
// retry. More tasks, may appear until the backoff has completed. The final |
|
// decision about the retry will be made in `connectionCreationBackoffDone(_:)` |
|
let eventLoop = self.connections.backoffNextConnectionAttempt(connectionID) |
|
|
|
let backoff = calculateBackoff(failedAttempt: self.failedConsecutiveConnectionAttempts) |
|
return .init( |
|
request: .none, |
|
connection: .scheduleBackoffTimer(connectionID, backoff: backoff, on: eventLoop) |
|
) |
|
|
|
case .shuttingDown: |
|
guard let (index, context) = self.connections.failConnection(connectionID) else { |
|
preconditionFailure("Failed to create a connection that is unknown to us?") |
|
} |
|
return self.nextActionForFailedConnection(at: index, context: context) |
|
|
|
case .shutDown: |
|
preconditionFailure("The pool is already shutdown all connections must already been torn down") |
|
} |
|
} |