Skip to content

Commit a57c4b3

Browse files
authored
[HTTP2ConnectionPool] added HTTP2StateMachine (#447)
1 parent 9696381 commit a57c4b3

9 files changed

+1073
-9
lines changed

Sources/AsyncHTTPClient/ConnectionPool/State Machine/HTTPConnectionPool+HTTP1Connections.swift

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,30 @@ extension HTTPConnectionPool {
189189
preconditionFailure("Unexpected state: Did not expect to have connections with this state in the state machine: \(self.state)")
190190
}
191191
}
192+
193+
enum MigrateAction {
194+
case removeConnection
195+
case keepConnection
196+
}
197+
198+
func migrateToHTTP2(_ context: inout HTTP1Connections.HTTP1ToHTTP2MigrationContext) -> MigrateAction {
199+
switch self.state {
200+
case .starting:
201+
context.starting.append((self.connectionID, self.eventLoop))
202+
return .removeConnection
203+
case .backingOff:
204+
context.backingOff.append((self.connectionID, self.eventLoop))
205+
return .removeConnection
206+
case .idle(let connection, since: _):
207+
// Idle connections can be removed right away
208+
context.close.append(connection)
209+
return .removeConnection
210+
case .leased:
211+
return .keepConnection
212+
case .closed:
213+
preconditionFailure("Unexpected state: Did not expect to have connections with this state in the state machine: \(self.state)")
214+
}
215+
}
192216
}
193217

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

325+
struct HTTP1ToHTTP2MigrationContext {
326+
var backingOff: [(Connection.ID, EventLoop)] = []
327+
var starting: [(Connection.ID, EventLoop)] = []
328+
var close: [Connection] = []
329+
}
330+
301331
// MARK: Connection creation
302332

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

518+
// MARK: Migration
519+
520+
mutating func migrateToHTTP2() -> HTTP1ToHTTP2MigrationContext {
521+
var migrationContext = HTTP1ToHTTP2MigrationContext()
522+
self.connections.removeAll { connection in
523+
switch connection.migrateToHTTP2(&migrationContext) {
524+
case .removeConnection:
525+
return true
526+
case .keepConnection:
527+
return false
528+
}
529+
}
530+
return migrationContext
531+
}
532+
488533
// MARK: Shutdown
489534

490535
mutating func shutdown() -> CleanupContext {
@@ -610,12 +655,12 @@ extension HTTPConnectionPool {
610655

611656
return nil
612657
}
613-
}
614658

615-
struct Stats {
616-
var idle: Int = 0
617-
var leased: Int = 0
618-
var connecting: Int = 0
619-
var backingOff: Int = 0
659+
struct Stats {
660+
var idle: Int = 0
661+
var leased: Int = 0
662+
var connecting: Int = 0
663+
var backingOff: Int = 0
664+
}
620665
}
621666
}

Sources/AsyncHTTPClient/ConnectionPool/State Machine/HTTPConnectionPool+HTTP1StateMachine.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ extension HTTPConnectionPool {
2424

2525
typealias Action = HTTPConnectionPool.StateMachine.Action
2626

27-
private var connections: HTTP1Connections
27+
private(set) var connections: HTTP1Connections
2828
private var failedConsecutiveConnectionAttempts: Int = 0
2929
/// the error from the last connection creation
3030
private var lastConnectFailure: Error?
3131

32-
private var requests: RequestQueue
32+
private(set) var requests: RequestQueue
3333
private var state: State = .running
3434

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

44-
// MARK: - Events -
44+
// MARK: - Events
4545

4646
mutating func executeRequest(_ request: Request) -> Action {
4747
switch self.state {

Sources/AsyncHTTPClient/ConnectionPool/State Machine/HTTPConnectionPool+HTTP2Connections.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ extension HTTPConnectionPool {
4949
}
5050
}
5151

52+
/// A connection is established and can potentially execute requests if not all streams are leased
53+
var isActive: Bool {
54+
switch self.state {
55+
case .active:
56+
return true
57+
case .starting, .backingOff, .draining, .closed:
58+
return false
59+
}
60+
}
61+
5262
/// A request can be scheduled on the connection
5363
var isAvailable: Bool {
5464
switch self.state {
@@ -326,6 +336,11 @@ extension HTTPConnectionPool {
326336

327337
// MARK: Connection creation
328338

339+
/// true if one ore more connections are active
340+
var hasActiveConnections: Bool {
341+
self.connections.contains { $0.isActive }
342+
}
343+
329344
/// used in general purpose connection scenarios to check if at least one connection exist, or if should we create a new one
330345
var hasConnectionThatCanOrWillBeAbleToExecuteRequests: Bool {
331346
self.connections.contains { $0.canOrWillBeAbleToExecuteRequests }

0 commit comments

Comments
 (0)