Skip to content

Commit 12c9e83

Browse files
authored
Merge pull request #43 from Automattic/mokagio/defer-s3-client-shutdown
Ensure we shutdown the S3 client even when operations fail
2 parents 05262fe + 906b879 commit 12c9e83

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

Sources/libhostmgr/S3Manager.swift

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,38 @@ public struct S3Manager: S3ManagerProtocol {
110110
private func withS3Client<T>(_ block: (SotoS3.S3) async throws -> T) async throws -> T {
111111
let awsClient = AWSClient(credentialProvider: credentialProvider, httpClientProvider: .createNew)
112112
let s3Client = SotoS3.S3(client: awsClient, region: Region(rawValue: self.region))
113-
let result = try await block(s3Client)
113+
114+
// The following code `try await` the given operation to execute with a
115+
// `SotoS3.S3` client created ad hoc and, once done, shuts down that
116+
// client.
117+
//
118+
// If something goes wrong while running the block, we still need to
119+
// shutdown the client, else the error from the block will be lost and
120+
// the program will fail with something like:
121+
//
122+
// SotoCore/AWSClient.swift:110: Assertion failed:
123+
// AWSClient not shut down before the deinit.
124+
// Please call client.syncShutdown() when no longer needed.
125+
//
126+
// It would be good to use `defer`, but it doesn't yet support asycn.
127+
// See https://forums.swift.org/t/async-rethrows-and-defer/58356.
128+
//
129+
// So, we use a `do catch` where in the catch we first shutdown the
130+
// client and then bubble up the error.
131+
let result: T
132+
do {
133+
result = try await block(s3Client)
134+
} catch {
135+
try await awsClient.shutdown()
136+
throw error
137+
}
138+
139+
// We need to shutdown the client also when `block` run successfully.
140+
//
141+
// This duplication with the call above will disappear once Swift will
142+
// give us a way to call `defer`.
114143
try await awsClient.shutdown()
144+
115145
return result
116146
}
117147

0 commit comments

Comments
 (0)