@@ -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