Skip to content

Commit 7383207

Browse files
authored
Add connectionCreationFailing and circuitBreak states to ConnectionPool (#610)
1 parent f047858 commit 7383207

File tree

6 files changed

+443
-81
lines changed

6 files changed

+443
-81
lines changed

Sources/ConnectionPoolModule/ConnectionPool.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ public struct ConnectionPoolConfiguration: Sendable {
116116
/// become idle.
117117
public var maximumConnectionHardLimit: Int
118118

119+
/// The amount of time to pass between the first failed connection
120+
/// before triggering the circuit breaker.
121+
public var circuitBreakerTripAfter: Duration
122+
119123
/// The time that a _preserved_ idle connection stays in the
120124
/// pool before it is closed.
121125
public var idleTimeout: Duration
@@ -125,6 +129,7 @@ public struct ConnectionPoolConfiguration: Sendable {
125129
self.minimumConnectionCount = 0
126130
self.maximumConnectionSoftLimit = 16
127131
self.maximumConnectionHardLimit = 16
132+
self.circuitBreakerTripAfter = .seconds(60)
128133
self.idleTimeout = .seconds(60)
129134
}
130135
}
@@ -151,7 +156,7 @@ public final class ConnectionPool<
151156
public typealias ConnectionFactory = @Sendable (ConnectionID, ConnectionPool<Connection, ConnectionID, ConnectionIDGenerator, Request, RequestID, KeepAliveBehavior, ObservabilityDelegate, Clock>) async throws -> ConnectionAndMetadata<Connection>
152157

153158
@usableFromInline
154-
typealias StateMachine = PoolStateMachine<Connection, ConnectionIDGenerator, ConnectionID, Request, Request.ID, CheckedContinuation<Void, Never>>
159+
typealias StateMachine = PoolStateMachine<Connection, ConnectionIDGenerator, ConnectionID, Request, Request.ID, CheckedContinuation<Void, Never>, Clock, Clock.Instant>
155160

156161
@usableFromInline
157162
let factory: ConnectionFactory
@@ -203,7 +208,8 @@ public final class ConnectionPool<
203208
var stateMachine = StateMachine(
204209
configuration: .init(configuration, keepAliveBehavior: keepAliveBehavior),
205210
generator: idGenerator,
206-
timerCancellationTokenType: CheckedContinuation<Void, Never>.self
211+
timerCancellationTokenType: CheckedContinuation<Void, Never>.self,
212+
clock: clock
207213
)
208214

209215
let (stream, continuation) = AsyncStream.makeStream(of: NewPoolActions.self)
@@ -574,6 +580,7 @@ extension PoolConfiguration {
574580
self.maximumConnectionHardLimit = configuration.maximumConnectionHardLimit
575581
self.keepAliveDuration = keepAliveBehavior.keepAliveFrequency
576582
self.idleTimeoutDuration = configuration.idleTimeout
583+
self.circuitBreakerTripAfter = configuration.circuitBreakerTripAfter
577584
}
578585
}
579586

Sources/ConnectionPoolModule/ConnectionPoolError.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ public struct ConnectionPoolError: Error, Hashable {
44
enum Base: Error, Hashable, Sendable {
55
case requestCancelled
66
case poolShutdown
7+
case connectionCreationCircuitBreakerTripped
78
}
89

910
@usableFromInline
@@ -22,4 +23,9 @@ public struct ConnectionPoolError: Error, Hashable {
2223
public static var poolShutdown: Self {
2324
ConnectionPoolError(.poolShutdown)
2425
}
26+
/// The connection pool has failed to make a connection after a defined time
27+
@inlinable
28+
public static var connectionCreationCircuitBreakerTripped: Self {
29+
ConnectionPoolError(.connectionCreationCircuitBreakerTripped)
30+
}
2531
}

0 commit comments

Comments
 (0)