Skip to content

Commit 5ae338c

Browse files
committed
Renamed destroy() to shutdown(), a pool now can't be used after calling shutdown()
1 parent 0b39b6c commit 5ae338c

File tree

2 files changed

+20
-11
lines changed

2 files changed

+20
-11
lines changed

Sources/PostgresConnectionPool/PoolError.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,7 @@ public enum PoolError: Error {
1111
case cancelled
1212
/// The connection to the database was unexpectedly closed.
1313
case connectionFailed
14+
/// The pool was already shut down.
15+
case poolDestroyed
1416

1517
}

Sources/PostgresConnectionPool/PostgresConnectionPool.swift

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@ public actor PostgresConnectionPool {
2828
private var available: Deque<PoolConnection> = []
2929
private var continuations: Deque<PoolContinuation> = []
3030

31-
private var didStartWatcherTask: Bool = false
31+
private var didStartWatcherTask = false
32+
private var didShutdown = false
3233

3334
// MARK: -
3435

36+
/// Initializes and configures a new pool. You should call ``shutdown()``
37+
/// when you are done with the pool.
3538
public init(configuration: PoolConfiguration, logger: Logger? = nil) {
3639
self.logger = logger ?? {
3740
var logger = Logger(label: configuration.applicationName)
@@ -64,8 +67,7 @@ public actor PostgresConnectionPool {
6467
}
6568

6669
deinit {
67-
assert(connections.isEmpty, "Must call destroy() before releasing a PostgresConnectionPool")
68-
try? eventLoopGroup.syncShutdownGracefully()
70+
assert(didShutdown, "Must call destroy() before releasing a PostgresConnectionPool")
6971
}
7072

7173
/// Takes one connection from the pool and dishes it out to the caller.
@@ -103,6 +105,8 @@ public actor PostgresConnectionPool {
103105
}
104106

105107
func getConnection() async throws -> PoolConnection {
108+
guard !didShutdown else { throw PoolError.poolDestroyed }
109+
106110
return try await withCheckedThrowingContinuation({ (continuation: PostgresCheckedContinuation) in
107111
self.continuations.append(PoolContinuation(continuation: continuation))
108112

@@ -128,20 +132,21 @@ public actor PostgresConnectionPool {
128132
}
129133
}
130134

131-
/// Releases all resources in the pool.
135+
/// Releases all resources in the pool and shuts down the event loop.
136+
/// All further uses of the pool will throw an error.
132137
///
133-
/// It's actually no problem to continue to use the PostgresConnectionPool after calling destroy(),
134-
/// it will just close all connections and abort any waiting continuations.
135-
public func destroy() async {
138+
/// Must be done here since Swift doesn't yet allow async deinit.
139+
public func shutdown() async {
136140
logger.debug("[\(poolName)] destroy()")
137141

142+
didShutdown = true
143+
144+
// Cancel all waiting continuations
138145
for poolContinuation in continuations {
139146
poolContinuation.continuation.resume(throwing: PoolError.cancelled)
140147
}
141-
continuations.removeAll()
142-
143-
available.removeAll()
144148

149+
// Close all open connections
145150
connections.forEach({ $0.state = .closed })
146151
for poolConnection in connections {
147152
if let connection = poolConnection.connection {
@@ -162,7 +167,9 @@ public actor PostgresConnectionPool {
162167
}
163168
}
164169
}
165-
connections.removeAll()
170+
171+
// Shut down the event loop.
172+
try? eventLoopGroup.syncShutdownGracefully()
166173
}
167174

168175
// MARK: - Private

0 commit comments

Comments
 (0)