15
15
import Logging
16
16
import NIOConcurrencyHelpers
17
17
import NIOCore
18
- import Synchronization
18
+
19
+ // To be re-enabled when we will be able to use Mutex on Linux
20
+ // import Synchronization
19
21
20
22
#if canImport(FoundationEssentials)
21
23
import FoundationEssentials
@@ -26,12 +28,18 @@ import Foundation
26
28
// This is our gardian to ensure only one LambdaRuntime is initialized
27
29
// We use a Mutex here to ensure thread safety
28
30
// We use Bool instead of LambdaRuntime<Handler> as the type here, as we don't know the concrete type that will be used
29
- private let _singleton = Mutex < Bool > ( false )
31
+ // We would love to use Mutex here, but this sadly crashes the compiler today (on Linux).
32
+ // private let _singleton = Mutex<Bool>(false)
33
+ private let _singleton : NIOLockedValueBox < Bool > = NIOLockedValueBox < Bool > ( false )
30
34
public enum LambdaRuntimeError : Error {
31
35
case moreThanOneLambdaRuntimeInstance
32
36
}
33
- public final class LambdaRuntime < Handler> : Sendable where Handler: StreamingLambdaHandler {
34
- let handlerMutex : Mutex < Handler ? >
37
+ // We need `@unchecked` Sendable here, as `NIOLockedValueBox` does not understand `sending` today.
38
+ // We don't want to use `NIOLockedValueBox` here anyway. We would love to use Mutex here, but this
39
+ // sadly crashes the compiler today (on Linux).
40
+ public final class LambdaRuntime < Handler> : @unchecked Sendable where Handler: StreamingLambdaHandler {
41
+ // TODO: We want to change this to Mutex as soon as this doesn't crash the Swift compiler on Linux anymore
42
+ let handlerMutex : NIOLockedValueBox < Handler ? >
35
43
let logger : Logger
36
44
let eventLoop : EventLoop
37
45
@@ -42,7 +50,14 @@ public final class LambdaRuntime<Handler>: Sendable where Handler: StreamingLamb
42
50
) throws ( LambdaRuntimeError) {
43
51
44
52
do {
45
- try _singleton. withLock {
53
+ // try _singleton.withLock {
54
+ // let alreadyCreated = $0
55
+ // guard alreadyCreated == false else {
56
+ // throw LambdaRuntimeError.moreThanOneLambdaRuntimeInstance
57
+ // }
58
+ // $0 = true
59
+ // }
60
+ try _singleton. withLockedValue {
46
61
let alreadyCreated = $0
47
62
guard alreadyCreated == false else {
48
63
throw LambdaRuntimeError . moreThanOneLambdaRuntimeInstance
@@ -55,7 +70,7 @@ public final class LambdaRuntime<Handler>: Sendable where Handler: StreamingLamb
55
70
fatalError ( " An unknown error occurred: \( error) " )
56
71
}
57
72
58
- self . handlerMutex = Mutex ( handler)
73
+ self . handlerMutex = NIOLockedValueBox ( handler)
59
74
self . eventLoop = eventLoop
60
75
61
76
// by setting the log level here, we understand it can not be changed dynamically at runtime
@@ -68,7 +83,7 @@ public final class LambdaRuntime<Handler>: Sendable where Handler: StreamingLamb
68
83
}
69
84
70
85
public func run( ) async throws {
71
- let handler = self . handlerMutex. withLock { handler in
86
+ let handler = self . handlerMutex. withLockedValue { handler in
72
87
let result = handler
73
88
handler = nil
74
89
return result
0 commit comments