Skip to content

Commit 660ae31

Browse files
committed
HTTP2StateMachine
1 parent 2bd8885 commit 660ae31

8 files changed

+606
-6
lines changed

Diff for: Sources/AsyncHTTPClient/ConnectionPool/State Machine/HTTPConnectionPool+HTTP1Connections.swift

+51-6
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.HTTP2ToHTTP1MigrationContext) -> 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 HTTP2ToHTTP1MigrationContext {
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() -> HTTP2ToHTTP1MigrationContext {
521+
var migrationContext = HTTP2ToHTTP1MigrationContext()
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
}

Diff for: Sources/AsyncHTTPClient/ConnectionPool/State Machine/HTTPConnectionPool+HTTP2Connections.swift

+15
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)