@@ -18,20 +18,112 @@ import NIOCore
18
18
// MARK: - SimpleLambdaHandler
19
19
20
20
/// Strongly typed, processing protocol for a Lambda that takes a user defined
21
- /// ``LambdaHandler /Event`` and returns a user defined
22
- /// ``LambdaHandler /Output`` asynchronously.
21
+ /// ``SimpleLambdaHandler /Event`` and returns a user defined
22
+ /// ``SimpleLambdaHandler /Output`` asynchronously.
23
23
///
24
24
/// - note: Most users should implement the ``LambdaHandler`` protocol instead
25
25
/// which defines the Lambda initialization method.
26
- @available ( macOS 12 , iOS 15 , tvOS 15 , watchOS 8 , * )
27
- public protocol SimpleLambdaHandler : LambdaHandler {
26
+ public protocol SimpleLambdaHandler {
27
+ /// The lambda function's input. In most cases this should be `Codable`. If your event originates from an
28
+ /// AWS service, have a look at [AWSLambdaEvents](https://github.com/swift-server/swift-aws-lambda-events),
29
+ /// which provides a number of commonly used AWS Event implementations.
30
+ associatedtype Event
31
+ /// The lambda function's output. Can be `Void`.
32
+ associatedtype Output
33
+
28
34
init ( )
35
+
36
+ /// The Lambda handling method.
37
+ /// Concrete Lambda handlers implement this method to provide the Lambda functionality.
38
+ ///
39
+ /// - parameters:
40
+ /// - event: Event of type `Event` representing the event or request.
41
+ /// - context: Runtime ``LambdaContext``.
42
+ ///
43
+ /// - Returns: A Lambda result ot type `Output`.
44
+ func handle( _ event: Event , context: LambdaContext ) async throws -> Output
45
+
46
+ /// Encode a response of type ``Output`` to `ByteBuffer`.
47
+ /// Concrete Lambda handlers implement this method to provide coding functionality.
48
+ /// - parameters:
49
+ /// - value: Response of type ``Output``.
50
+ /// - buffer: A `ByteBuffer` to encode into, will be overwritten.
51
+ ///
52
+ /// - Returns: A `ByteBuffer` with the encoded version of the `value`.
53
+ func encode( value: Output , into buffer: inout ByteBuffer ) throws
54
+
55
+ /// Decode a `ByteBuffer` to a request or event of type ``Event``.
56
+ /// Concrete Lambda handlers implement this method to provide coding functionality.
57
+ ///
58
+ /// - parameters:
59
+ /// - buffer: The `ByteBuffer` to decode.
60
+ ///
61
+ /// - Returns: A request or event of type ``Event``.
62
+ func decode( buffer: ByteBuffer ) throws -> Event
63
+ }
64
+
65
+ final class CodableSimpleLambdaHandler < Underlying: SimpleLambdaHandler > : ByteBufferLambdaHandler {
66
+ private let handler : Underlying
67
+ private var outputBuffer : ByteBuffer
68
+
69
+ @inlinable
70
+ static func makeHandler( context: LambdaInitializationContext ) -> EventLoopFuture < CodableSimpleLambdaHandler > {
71
+ let promise = context. eventLoop. makePromise ( of: CodableSimpleLambdaHandler< Underlying> . self )
72
+ promise. completeWithTask {
73
+ let handler = Underlying ( )
74
+ return CodableSimpleLambdaHandler ( handler: handler, allocator: context. allocator)
75
+ }
76
+ return promise. futureResult
77
+ }
78
+
79
+ @inlinable
80
+ init ( handler: Underlying , allocator: ByteBufferAllocator ) {
81
+ self . handler = handler
82
+ self . outputBuffer = allocator. buffer ( capacity: 1024 * 1024 )
83
+ }
84
+
85
+ @inlinable
86
+ func handle( _ buffer: ByteBuffer , context: LambdaContext ) -> EventLoopFuture < ByteBuffer ? > {
87
+ let promise = context. eventLoop. makePromise ( of: ByteBuffer ? . self)
88
+ promise. completeWithTask {
89
+ let input : Underlying . Event
90
+ do {
91
+ input = try self . handler. decode ( buffer: buffer)
92
+ } catch {
93
+ throw CodecError . requestDecoding ( error)
94
+ }
95
+
96
+ let output = try await self . handler. handle ( input, context: context)
97
+
98
+ do {
99
+ self . outputBuffer. clear ( )
100
+ try self . handler. encode ( value: output, into: & self . outputBuffer)
101
+ return self . outputBuffer
102
+ } catch {
103
+ throw CodecError . responseEncoding ( error)
104
+ }
105
+ }
106
+ return promise. futureResult
107
+ }
108
+ }
109
+
110
+ /// Implementation of `ByteBuffer` to `Void` decoding.
111
+ extension SimpleLambdaHandler where Output == Void {
112
+ @inlinable
113
+ public func encode( value: Output , into buffer: inout ByteBuffer ) throws { }
29
114
}
30
115
31
- @available ( macOS 12 , iOS 15 , tvOS 15 , watchOS 8 , * )
32
116
extension SimpleLambdaHandler {
33
- public init ( context: LambdaInitializationContext ) async throws {
34
- self . init ( )
117
+ /// Initializes and runs the Lambda function.
118
+ ///
119
+ /// If you precede your ``SimpleLambdaHandler`` conformer's declaration with the
120
+ /// [@main](https://docs.swift.org/swift-book/ReferenceManual/Attributes.html#ID626)
121
+ /// attribute, the system calls the conformer's `main()` method to launch the lambda function.
122
+ ///
123
+ /// The lambda runtime provides a default implementation of the method that manages the launch
124
+ /// process.
125
+ public static func main( ) {
126
+ _ = Lambda . run ( configuration: . init( ) , handlerType: Self . self)
35
127
}
36
128
}
37
129
@@ -44,7 +136,6 @@ extension SimpleLambdaHandler {
44
136
/// - note: Most users should implement this protocol instead of the lower
45
137
/// level protocols ``EventLoopLambdaHandler`` and
46
138
/// ``ByteBufferLambdaHandler``.
47
- @available ( macOS 12 , iOS 15 , tvOS 15 , watchOS 8 , * )
48
139
public protocol LambdaHandler {
49
140
/// The lambda function's input. In most cases this should be `Codable`. If your event originates from an
50
141
/// AWS service, have a look at [AWSLambdaEvents](https://github.com/swift-server/swift-aws-lambda-events),
@@ -90,7 +181,6 @@ public protocol LambdaHandler {
90
181
func decode( buffer: ByteBuffer ) throws -> Event
91
182
}
92
183
93
- @available ( macOS 12 , iOS 15 , tvOS 15 , watchOS 8 , * )
94
184
final class CodableLambdaHandler < Underlying: LambdaHandler > : ByteBufferLambdaHandler {
95
185
private let handler : Underlying
96
186
private var outputBuffer : ByteBuffer
@@ -137,17 +227,15 @@ final class CodableLambdaHandler<Underlying: LambdaHandler>: ByteBufferLambdaHan
137
227
}
138
228
139
229
/// Implementation of `ByteBuffer` to `Void` decoding.
140
- @available ( macOS 12 , iOS 15 , tvOS 15 , watchOS 8 , * )
141
230
extension LambdaHandler where Output == Void {
142
231
@inlinable
143
232
public func encode( value: Output , into buffer: inout ByteBuffer ) throws { }
144
233
}
145
234
146
- @available ( macOS 12 , iOS 15 , tvOS 15 , watchOS 8 , * )
147
235
extension LambdaHandler {
148
236
/// Initializes and runs the Lambda function.
149
237
///
150
- /// If you precede your ``ByteBufferLambdaHandler `` conformer's declaration with the
238
+ /// If you precede your ``LambdaHandler `` conformer's declaration with the
151
239
/// [@main](https://docs.swift.org/swift-book/ReferenceManual/Attributes.html#ID626)
152
240
/// attribute, the system calls the conformer's `main()` method to launch the lambda function.
153
241
///
@@ -161,7 +249,6 @@ extension LambdaHandler {
161
249
/// unchecked sendable wrapper for the handler
162
250
/// this is safe since lambda runtime is designed to calls the handler serially
163
251
@usableFromInline
164
- @available ( macOS 12 , iOS 15 , tvOS 15 , watchOS 8 , * )
165
252
internal struct UncheckedSendableHandler < Underlying: LambdaHandler , Event, Output> : @unchecked Sendable where Event == Underlying . Event , Output == Underlying . Output {
166
253
@usableFromInline
167
254
let underlying : Underlying
@@ -283,7 +370,7 @@ internal final class CodableEventLoopLambdaHandler<Underlying: EventLoopLambdaHa
283
370
extension EventLoopLambdaHandler {
284
371
/// Initializes and runs the Lambda function.
285
372
///
286
- /// If you precede your ``ByteBufferLambdaHandler `` conformer's declaration with the
373
+ /// If you precede your ``EventLoopLambdaHandler `` conformer's declaration with the
287
374
/// [@main](https://docs.swift.org/swift-book/ReferenceManual/Attributes.html#ID626)
288
375
/// attribute, the system calls the conformer's `main()` method to launch the lambda function.
289
376
///
0 commit comments