Skip to content

Commit 8cf4416

Browse files
committed
Fixes for Swift 6.
1 parent 2ecddcf commit 8cf4416

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed

Sources/AWSLambdaRuntimeCore/Lambda+LocalServer.swift

+18-9
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ private struct LambdaHTTPServer {
9393
case serverReturned(Swift.Result<Void, any Error>)
9494
}
9595

96+
struct UnsafeTransferBox<Value>: @unchecked Sendable {
97+
let value: Value
98+
99+
init(value: sending Value) {
100+
self.value = value
101+
}
102+
}
103+
96104
static func withLocalServer<Result: Sendable>(
97105
invocationEndpoint: String?,
98106
host: String = "127.0.0.1",
@@ -135,18 +143,13 @@ private struct LambdaHTTPServer {
135143

136144
let server = LambdaHTTPServer(invocationEndpoint: invocationEndpoint)
137145

138-
// We are handling each incoming connection in a separate child task. It is important
139-
// to use a discarding task group here which automatically discards finished child tasks.
140-
// A normal task group retains all child tasks and their outputs in memory until they are
141-
// consumed by iterating the group or by exiting the group. Since, we are never consuming
142-
// the results of the group we need the group to automatically discard them; otherwise, this
143-
// would result in a memory leak over time.
146+
// Sadly the Swift compiler does not understand that the passed in closure will only be
147+
// invoked once. Because of this we need an unsafe transfer box here. Buuuh!
148+
let closureBox = UnsafeTransferBox(value: closure)
144149
let result = await withTaskGroup(of: TaskResult<Result>.self, returning: Swift.Result<Result, any Error>.self) { group in
145-
146-
let c = closure
147150
group.addTask {
151+
let c = closureBox.value
148152
do {
149-
150153
let result = try await c()
151154
return .closureResult(.success(result))
152155
} catch {
@@ -156,6 +159,12 @@ private struct LambdaHTTPServer {
156159

157160
group.addTask {
158161
do {
162+
// We are handling each incoming connection in a separate child task. It is important
163+
// to use a discarding task group here which automatically discards finished child tasks.
164+
// A normal task group retains all child tasks and their outputs in memory until they are
165+
// consumed by iterating the group or by exiting the group. Since, we are never consuming
166+
// the results of the group we need the group to automatically discard them; otherwise, this
167+
// would result in a memory leak over time.
159168
try await withThrowingDiscardingTaskGroup { taskGroup in
160169
try await channel.executeThenClose { inbound in
161170
for try await connectionChannel in inbound {

0 commit comments

Comments
 (0)