diff --git a/Sources/MongoSwift/ConnectionPool.swift b/Sources/MongoSwift/ConnectionPool.swift index b0d43d5e6..fa75b0c54 100644 --- a/Sources/MongoSwift/ConnectionPool.swift +++ b/Sources/MongoSwift/ConnectionPool.swift @@ -59,7 +59,7 @@ internal class ConnectionPool { } /// Closes the pool, cleaning up underlying resources. This method blocks as it sends `endSessions` to the server. - internal func close() { + internal func shutdown() { switch self.state { case let .open(pool): mongoc_client_pool_destroy(pool) diff --git a/Sources/MongoSwift/MongoClient.swift b/Sources/MongoSwift/MongoClient.swift index 833c6c7d1..f957c072d 100644 --- a/Sources/MongoSwift/MongoClient.swift +++ b/Sources/MongoSwift/MongoClient.swift @@ -288,12 +288,13 @@ public class MongoClient { assert(self.isClosed, "MongoClient was not closed before deinitialization") } - /// Closes this `MongoClient`. Call this method exactly once when you are finished using the client. You must - /// ensure that all operations using the client have completed before calling this. The returned future must be - /// fulfilled before the `EventLoopGroup` provided to this client's constructor is shut down. - public func close() -> EventLoopFuture { + /// Shuts this `MongoClient` down, closing all connection to the server and cleaning up internal state. + /// Call this method exactly once when you are finished using the client. You must ensure that all operations + /// using the client have completed before calling this. The returned future must be fulfilled before the + /// `EventLoopGroup` provided to this client's constructor is shut down. + public func shutdown() -> EventLoopFuture { return self.operationExecutor.execute { - self.connectionPool.close() + self.connectionPool.shutdown() self.isClosed = true } .flatMap { @@ -301,6 +302,22 @@ public class MongoClient { } } + /** + * Shuts this `MongoClient` down in a blocking fashion, closing all connections to the server and cleaning up + * internal state. + * + * Call this method exactly once when you are finished using the client. You must ensure that all operations + * using the client have completed before calling this. + * + * This method must complete before the `EventLoopGroup` provided to this client's constructor is shut down. + */ + public func syncShutdown() { + self.connectionPool.shutdown() + self.isClosed = true + // TODO: SWIFT-349 log any errors encountered here. + try? self.operationExecutor.syncClose() + } + /// Starts a new `ClientSession` with the provided options. When you are done using this session, you must call /// `ClientSession.end()` on it. public func startSession(options: ClientSessionOptions? = nil) -> ClientSession { diff --git a/Sources/MongoSwift/Operations/Operation.swift b/Sources/MongoSwift/Operations/Operation.swift index 8775807f2..a92435286 100644 --- a/Sources/MongoSwift/Operations/Operation.swift +++ b/Sources/MongoSwift/Operations/Operation.swift @@ -37,6 +37,11 @@ internal class OperationExecutor { return promise.futureResult } + /// Closes the executor's underlying thread pool synchronously. + internal func syncClose() throws { + try self.threadPool.syncShutdownGracefully() + } + internal func execute( _ operation: T, using connection: Connection? = nil, diff --git a/Sources/MongoSwiftSync/MongoClient.swift b/Sources/MongoSwiftSync/MongoClient.swift index d1cc4d76c..40d2296d0 100644 --- a/Sources/MongoSwiftSync/MongoClient.swift +++ b/Sources/MongoSwiftSync/MongoClient.swift @@ -53,7 +53,7 @@ public class MongoClient { deinit { do { - try self.asyncClient.close().wait() + try self.asyncClient.shutdown().wait() } catch { assertionFailure("Error closing async client: \(error)") } diff --git a/Tests/MongoSwiftTests/AsyncTestUtils.swift b/Tests/MongoSwiftTests/AsyncTestUtils.swift index aa07ecef0..27b19900d 100644 --- a/Tests/MongoSwiftTests/AsyncTestUtils.swift +++ b/Tests/MongoSwiftTests/AsyncTestUtils.swift @@ -22,7 +22,7 @@ extension MongoClient { internal func syncCloseOrFail() { do { - try self.close().wait() + try self.shutdown().wait() } catch { XCTFail("Error closing test client: \(error)") } diff --git a/Tests/MongoSwiftTests/MongoClientTests.swift b/Tests/MongoSwiftTests/MongoClientTests.swift index 086eb40a8..3a85b1108 100644 --- a/Tests/MongoSwiftTests/MongoClientTests.swift +++ b/Tests/MongoSwiftTests/MongoClientTests.swift @@ -8,7 +8,7 @@ final class MongoClientTests: MongoSwiftTestCase { let elg = MultiThreadedEventLoopGroup(numberOfThreads: 1) defer { elg.syncShutdownOrFail() } let client = try MongoClient(using: elg) - try client.close().wait() + try client.shutdown().wait() expect(try client.listDatabases().wait()).to(throwError(MongoClient.ClosedClientError)) }