Skip to content

[HTTP2ConnectionPool] added HTTP2StateMachine #447

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Oct 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,30 @@ extension HTTPConnectionPool {
preconditionFailure("Unexpected state: Did not expect to have connections with this state in the state machine: \(self.state)")
}
}

enum MigrateAction {
case removeConnection
case keepConnection
}

func migrateToHTTP2(_ context: inout HTTP1Connections.HTTP1ToHTTP2MigrationContext) -> MigrateAction {
switch self.state {
case .starting:
context.starting.append((self.connectionID, self.eventLoop))
return .removeConnection
case .backingOff:
context.backingOff.append((self.connectionID, self.eventLoop))
return .removeConnection
case .idle(let connection, since: _):
// Idle connections can be removed right away
context.close.append(connection)
return .removeConnection
case .leased:
return .keepConnection
case .closed:
preconditionFailure("Unexpected state: Did not expect to have connections with this state in the state machine: \(self.state)")
}
}
}

/// A structure to hold the currently active HTTP/1.1 connections.
Expand Down Expand Up @@ -298,6 +322,12 @@ extension HTTPConnectionPool {
var connectionsStartingForUseCase: Int
}

struct HTTP1ToHTTP2MigrationContext {
var backingOff: [(Connection.ID, EventLoop)] = []
var starting: [(Connection.ID, EventLoop)] = []
var close: [Connection] = []
}

// MARK: Connection creation

mutating func createNewConnection(on eventLoop: EventLoop) -> Connection.ID {
Expand Down Expand Up @@ -485,6 +515,21 @@ extension HTTPConnectionPool {
return (index, context)
}

// MARK: Migration

mutating func migrateToHTTP2() -> HTTP1ToHTTP2MigrationContext {
var migrationContext = HTTP1ToHTTP2MigrationContext()
self.connections.removeAll { connection in
switch connection.migrateToHTTP2(&migrationContext) {
case .removeConnection:
return true
case .keepConnection:
return false
}
}
return migrationContext
}

// MARK: Shutdown

mutating func shutdown() -> CleanupContext {
Expand Down Expand Up @@ -610,12 +655,12 @@ extension HTTPConnectionPool {

return nil
}
}

struct Stats {
var idle: Int = 0
var leased: Int = 0
var connecting: Int = 0
var backingOff: Int = 0
struct Stats {
var idle: Int = 0
var leased: Int = 0
var connecting: Int = 0
var backingOff: Int = 0
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ extension HTTPConnectionPool {

typealias Action = HTTPConnectionPool.StateMachine.Action

private var connections: HTTP1Connections
private(set) var connections: HTTP1Connections
private var failedConsecutiveConnectionAttempts: Int = 0
/// the error from the last connection creation
private var lastConnectFailure: Error?

private var requests: RequestQueue
private(set) var requests: RequestQueue
private var state: State = .running

init(idGenerator: Connection.ID.Generator, maximumConcurrentConnections: Int) {
Expand All @@ -41,7 +41,7 @@ extension HTTPConnectionPool {
self.requests = RequestQueue()
}

// MARK: - Events -
// MARK: - Events

mutating func executeRequest(_ request: Request) -> Action {
switch self.state {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ extension HTTPConnectionPool {
}
}

/// A connection is established and can potentially execute requests if not all streams are leased
var isActive: Bool {
switch self.state {
case .active:
return true
case .starting, .backingOff, .draining, .closed:
return false
}
}

/// A request can be scheduled on the connection
var isAvailable: Bool {
switch self.state {
Expand Down Expand Up @@ -326,6 +336,11 @@ extension HTTPConnectionPool {

// MARK: Connection creation

/// true if one ore more connections are active
var hasActiveConnections: Bool {
self.connections.contains { $0.isActive }
}

/// used in general purpose connection scenarios to check if at least one connection exist, or if should we create a new one
var hasConnectionThatCanOrWillBeAbleToExecuteRequests: Bool {
self.connections.contains { $0.canOrWillBeAbleToExecuteRequests }
Expand Down
Loading